CSS翻牌组件需求:实现前后翻牌同方向翻转效果
解决CSS翻牌双向同方向翻转问题
要实现背面翻转为正面时和正面翻背面使用相同的翻转方向,不能依赖classList.toggle的状态切换(移除类会触发反向过渡),需要改为每次点击都触发一次单向的翻转动画,同时同步卡片的状态逻辑。
方案实现:
1. CSS 调整
.scene { width: 200px; height: 260px; perspective: 600px; } .card { position: relative; width: 100%; height: 100%; cursor: pointer; transform-style: preserve-3d; transition: none; /* 移除默认过渡,改用自定义动画 */ } .card__face { position: absolute; width: 100%; height: 100%; line-height: 260px; color: white; text-align: center; font-weight: bold; font-size: 40px; backface-visibility: hidden; } .card__face--front { background: red; } .card__face--back { background: blue; transform: rotateY(180deg); } /* 定义和原效果一致的单向翻转动画 */ @keyframes flipForward { 0% { transform: translateX(0) rotateY(0); } 50% { transform: translateX(-100%) rotateY(-90deg); } 100% { transform: translateX(0) rotateY(-180deg); } } /* 触发动画的类 */ .card.flip-animation { animation: flipForward 0.6s forwards; }
2. JavaScript 调整
不再使用toggle切换类,改为跟踪卡片状态,每次点击触发单向动画,动画结束后更新状态:
const cards = document.querySelectorAll('.card'); cards.forEach(card => { let isFlipped = false; // 标记当前是否为背面状态 card.addEventListener('click', () => { // 添加动画类触发翻转 card.classList.add('flip-animation'); // 动画结束后清理并更新状态 card.addEventListener('animationend', () => { card.classList.remove('flip-animation'); isFlipped = !isFlipped; // 保持最终翻转状态,360deg和0视觉效果一致,实现循环翻转 card.style.transform = isFlipped ? 'rotateY(-180deg)' : 'rotateY(-360deg)'; if (!isFlipped) setTimeout(() => card.style.transform = 'rotateY(0)', 0); }, { once: true }); // 确保事件只执行一次 }); });
3. HTML 保持不变
<div class="scene scene--card"> <div class="card"> <div class="card__face card__face--front">front</div> <div class="card__face card__face--back">back</div> </div> </div>
核心思路:
- 放弃状态切换的逻辑,改为每次点击触发固定方向的翻转动画,和原正面翻背面的轨迹完全一致。
- 用变量跟踪当前卡片状态,动画结束后更新transform值,确保视觉状态和逻辑匹配。
- 通过关键帧动画还原原有的平移+翻转效果,保证双向翻转的视觉一致性。
内容的提问来源于stack exchange,提问作者Stéphane GRILLON
相关产品推荐
相关产品推荐

