面试官:知道用CSS3玩转旋转卡片的正确姿势吗?
我:这个当然知道啊,我精通css3,这可难不倒我
面试官:好,那你实现一个旋转卡片效果,这里有两张图片,你搞成旋转开包的样子
我:好家伙,你要说到开包,这我可不困了,tnnd黑心游戏厂商,@#@#*@#!为了坑我们这些肥宅游戏玩家氪金开包,各种花里胡哨的下三滥手段都玩个遍,我咒它们早日倒闭!
......
面试官:好家伙,我也这么觉得的,同是天涯沦落人,小伙子,明天来我这上班吧,今后带你吃香的喝辣的玩男人都爱玩的(游戏),一起搞大事业,干趴黑心厂家,这下割玩家韭菜的就是我们了,岂不美哉......
思路
父div使用相对定位包裹着两个子div(名为son1,son2)
两个子元素使用绝对定位定位在同一个位置
初始时一个div翻转到后面隐藏,另一个在前面显示
当鼠标悬停或点击触发旋转时,前面的子元素旋转180度,到背面隐藏;背面的元素旋转360度,转到前面显示
核心:
.前者, .后者{
/*谁在后面谁就被隐藏起来,即背面不可见*/
backface-visibility: hidden;
transition: all 1.5s;
}
.后者{
/*刚开始让后者转到后面去*/
transform: rotateY(180deg);
}
触发旋转时 前者{
/*鼠标悬浮在元素上时,前面一层的元素正旋转180度,实现前者旋转到背面,达到隐藏的效果*/
transform: rotateY(180deg);
}
触发旋转时 后者{
/*鼠标悬浮在元素上时,前面一层的元素正旋转360度,实现前者旋转到前面,达到显示的效果 */
transform: rotateY(360deg);
}如果想附加一些角度效果,形成仰视旋转的样子,可使用perspective属性。
demo1 旋转少女
开包游戏都玩过吧?卡片转啊转,开出几个老婆出来,好家伙,转来转去真可爱。
效果
代码实现
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>卡片翻转title>
<style>.outside {width: 220px;height: 276px;cursor: pointer;margin: 50px auto;position: relative;perspective: 500px;
}.outside img {max-width: 220px;
}.front_img, .back_img {width: 100%;height: 100%;position: absolute;/* 子元素相对于父元素使用绝对定位,两个子元素都定位到同一个位置,实现重叠的效果 */top: 0;left: 0;perspective: 1000px;backface-visibility: hidden;transition: all 1.5s;
}.back_img {transform: rotateY(180deg);
}.outside:hover .front_img {transform: rotateY(180deg);
}.outside:hover .back_img {/*鼠标悬浮在元素上时,前面一层的图片正旋转360度,实现前面的图片旋转到前面,达到显示的效果 */transform: rotateY(360deg);
}style>
head>
<body>
<div>
<div class="outside">
<div class="front_img">
<img src="https://i0.hdslb.com/bfs/article/1e3c40b20b678715fc280a0d102589b3393526a9.jpg@1320w_1904h.webp" alt="front_picture"/>
div>
<div class="back_img">
<img src="https://i0.hdslb.com/bfs/article/9d34dd08bf746e07bcb55a08d504123cfd7cbb27.jpg@1320w_1980h.webp"alt="back_ground"/>
div>
div>
div>
body>
html>
demo2 旋转表单
实现一个好看地一批的登录表单?来,这就撸一个出来。
效果
关键思路
- 通过js给父元素动态添加registering(或者叫其它)的类名
- 有login在时,
.registering下的
.demo-login旋转180度到前后面去,
.demo-register`旋转到前面来 - 没login时,
.registering .demo-register
旋转180度到前后面去,.demo-login
旋转到前面来
/* 关键部分 */
.registering .demo-login, .demo-register {
/* translate按哪个轴进行移动 水平方向:正右负左 垂直:负上正下 元素中心和父元素中心保持对齐 水平垂直居中 */
transform: perspective(1000px) translate(-50%, -50%) rotateY(180deg);
backface-visibility: hidden;
transition: all 1.5s;
}
.registering .demo-register, .demo-login {
transform: perspective(1000px) translate(-50%, -50%) rotateY(0deg);
backface-visibility: hidden;
transition: all 1.5s;
}
代码
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="https://at.alicdn.com/t/font_1156682_y7tsfj12kx.css">
<style>
* {margin: 0;padding: 0;box-sizing: border-box;
}body, html {height: 100%;
}body {font: 18px/1.5em Arial;color: #000;/*background: url("http://pic1.win4000.com/wallpaper/0/544b36fae2969.jpg") center center no-repeat;*/background-size: cover;
}a {color: #000;/* 取消a标签的下划线 */text-decoration: none;
}ul {/* 取消列表的点 */list-style: none;
}.clearfix:after {content: '';display: block;clear: both;
}header {height: 50px;position: relative;
}header a {color: #000;border: 1px solid blue;border-radius: 50%;position: absolute;top: 15px;right: 20px;
}.demo {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);width: 500px;padding: 16px;background-color: #fff;box-shadow: 0 3px 4px 5px rgba(0, 0, 0, 0.2);
}.demo-login, .demo-register {border: 2px solid #345dc2;
}.demo .close {position: absolute;top: 9px;right: -13px;
}.demo ul {/*border: 1px solid black;*/width: 40%;margin: 18px auto;
}.demo ul li:first-child {float: left;margin: 5px 10px;text-align: center;
}.demo ul li:last-child {float: right;margin: 5px 10px;text-align: center;
}.demo li a {font-size: 20px;color: #666;
}.demo li a.active {border-bottom: 3px solid #444;
}.demo .info {color: #ff0037;font-size: 12px;margin: 0 62px;
}.demo .username, .password {border: 1px solid #ccc;margin: 25px auto;width: 370px;
}.demo span {display: inline-block;margin: 10px 8px;
}.demo .text {/* 取消input的最外层框 */border: none;height: 46px;width: 330px;
}.demo input {/* outline (轮廓)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。 */outline: medium;padding: 5px 12px;
}.demo .input-field {width: 50%;/*border: 1px solid black;*//*display: inline-block;*/background: #fff;margin: 0 auto 20px;box-shadow: 0 0 2px rgba(0, 0, 0, 0.4);
}.demo input[type="submit"] { /* 按钮美化 */width: 100%; /* 宽度 */height: 100%; /* 高度 */border-width: 0; /* 边框宽度 */border-radius: 10px; /* 边框半径 */background: #1E90FF; /* 背景颜色 */cursor: pointer; /* 鼠标移入按钮范围时出现手势 */outline: none; /* 不显示轮廓线 */color: white; /* 字体颜色 */font-size: 17px; /* 字体大小 */
}.demo input[type="submit"]:hover { /* 鼠标移入按钮范围时改变颜色 */background: #5599FF;
}/* 关键部分 */.registering .demo-login, .demo-register {/* translate按哪个轴进行移动 水平方向:正右负左 垂直:负上正下 元素中心和父元素中心保持对齐 水平垂直居中 */transform: perspective(1000px) translate(-50%, -50%) rotateY(180deg);backface-visibility: hidden;transition: all 1.5s;
}.registering .demo-register, .demo-login {transform: perspective(1000px) translate(-50%, -50%) rotateY(0deg);backface-visibility: hidden;transition: all 1.5s;
}style>
head>
<body>
<main>
<div class="content">
<div class="demo demo-login">
<a href="#" class="iconfont icon-guanbi close">a>
<ul class="clearfix">
<li><a href="#" class="login active">登录a>li>
<li><a href="#" class="register active">注册a>li>
ul>
<div class="info">div>
<form action="/login" method="post">
<div class="username">
<span class="iconfont icon-login2">span>
<label>
<input class="text" type="text" name="username" placeholder="请输入用户名">
label>
div>
<div class="password">
<span class="iconfont icon-mima">span>
<label>
<input class="text" type="password" name="password" placeholder="请输入密码">
label>
div>
<div class="input-field">
<input type="submit" value="登录">
div>
form>
div>
<div class="demo demo-register">
<a href="#" class="iconfont icon-guanbi close">a>
<ul class="clearfix">
<li><a href="#" class="login active">登录a>li>
<li><a href="#" class="register active">注册a>li>
ul>
<div class="info">div>
<form action="/register" method="post">
<div class="username">
<span class="iconfont icon-login2">span>
<input class="text" type="text" name="username" placeholder="输入用户名">
div>
<div class="password">
<span class="iconfont icon-mima">span>
<input class="text" type="password" name="password" placeholder="输入密码">
div>
<div class="password">
<span class="iconfont icon-mima">span>
<input class="text" type="password" name="password" placeholder="再次输入密码">
div>
<div class="input-field">
<input type="submit" value="注册">
div>
form>
div>
div>
main>
<script>function $(selector) {return document.querySelector(selector);
}// 事件代理
$('.content').addEventListener('click', function (e) {
e.stopPropagation();console.log(e.target);// 切换到登录状态if (e.target.classList.contains('login')) {console.log("切换到登录状态")
$('.content li .register').classList.remove('active');
$('main').classList.remove('registering');
}// 切换到注册状态if (e.target.classList.contains('register')) {console.log("切换到注册状态")
$('.content .demo-register li .login').classList.remove('active');
$('main').classList.add('registering');
}if (e.target.classList.contains('close')) {
$('.content').style.display = 'none';
}
})// 点击空白处关闭document.addEventListener('click', function (e) {
e.stopPropagation();
$('.content').style.display = 'none';
})// 初始默认为登录状态
$('.content li .register').classList.remove('active');script>
body>
html>