最小翻牌demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
/* 简单样式声明,可忽略 */
* {
margin: 0;
padding: 0;
}
.card-style {
margin: 0 auto;
width: 100px;
height: 200px;
border-left: 3px solid salmon;
border-bottom: 3px solid salmon;
border-top: 3px solid yellow;
border-right: 3px solid yellow;
color: #fff;
}
/* 简单样式声明结束 */
.card {
position: relative;
transition: transform 0.5s linear;
transform-style: preserve-3d;
}
.transform {
transform: rotateY(180deg);
}
.front {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #888;
backface-visibility: hidden;
}
.end {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: seagreen;
transform: rotateY(-180deg);
backface-visibility: hidden;
}
</style>
</head>
<body>
<div class="card card-style">
card
<div class="front"></div>
<div class="end"></div>
</div>
<script>
// 最小化demo
// 一张牌,翻牌+移动
const card = document.querySelector('.card')
card.addEventListener('click', function() {
if (card.className.match('transform')) {
card.classList.remove('transform')
} else {
card.classList.add('transform')
}
})
</script>
</body>
</html>
点击查看【codepen】
原理分析
- 主要翻转效果实现:
- 点击时给父元素添加
transform: rotateY(180deg);
- 父元素设置初始值
transform-style: preserve-3d;
设置元素的子元素是位于3d空间中,所以上面的元素会遮盖下面的元素。transform-style(MDN) - 背面的元素设置初始值
transform: rotate(-180deg);
- 父元素设置
transition
- 当父元素进行180度的翻转时,背面元素被置于正面位置,因为元素处于3d空间内,所以会遮盖掉当前翻转到背面的正面元素,从而形成翻牌效果。
- 让翻转效果更自然:
backface-visibility: hidden;
设置当元素背向观察者时不可见。并且切换可见性的时机为 rotate(90deg) 的时候。backface-visibility(MDN)- 如果仅用主要翻转效果实现,那么切换翻牌卡面的时机会是翻转结束时,也就是 rotate(180deg) 并且 transition 完成时,变化滞后,体验不好。
- 配合
backface-visibility
,切换时机会变为 rotate(90deg) 时