最小翻牌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) 时