CSS 3D翻牌本质是绕Y轴旋转180°,需父容器设perspective(1000px~2000px)、子元素设transform-style: preserve-3d及backface-visibility: hidden,背面初始化rotateY(180deg),用class切换+transition实现惯性翻转,多位数字须按位分离独立控制。

用 CSS 3D transform 实现翻牌,不是靠 JS 动画驱动
翻牌效果的本质是绕 Y 轴旋转 180°,必须启用 3D 渲染上下文,否则 rotateY 无效或降级为 2D。常见错误是只写 transform: rotateY(180deg) 却没设 transform-style: preserve-3d 和容器的 perspective,结果前后两面叠在一起、看不见翻转过程。
关键点:
-
perspective必须加在翻牌容器(父元素)上,值太小(如100px)会畸变,太大(如5000px)则翻转像平移;推荐1000px~2000px - 子元素(正面/背面)需设
transform-style: preserve-3d,否则子元素自身不参与 3D 空间计算 - 背面必须加
transform: rotateY(180deg)初始化朝向,否则翻转后内容是镜像的 - 避免对
body或全局容器设perspective,会影响页面其他元素
数字翻牌动画要用 transition + class 切换,别用 setInterval 强刷
数字翻牌(比如倒计时、分数变化)不是单纯旋转容器,而是每变一位就触发一次翻牌。强行用 setInterval 频繁修改 transform 会导致卡顿、跳帧,且无法精准控制单个数字位的翻转节奏。
正确做法是为每个数字位封装独立翻牌单元,用 class 控制状态:
立即学习“前端免费学习笔记(深入)”;
<div class="digit"> <div class="front">3</div> <div class="back">4</div> </div>
JS 只负责切换 is-flipped 类:
digitEl.classList.add('is-flipped');
// 翻完后移除,供下次复用
setTimeout(() => digitEl.classList.remove('is-flipped'), 600);
CSS 中用 transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 模拟惯性翻转感——别用 ease-in-out,它会让中间段太慢,显得拖沓。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
移动端 Safari 上 backface-visibility 必须显式设为 hidden
iOS Safari(尤其 iOS 15+)对 backface-visibility 的默认行为不一致,即使写了 transform: rotateY(180deg),背面仍可能“透出”或闪烁。这不是 bug,是渲染策略差异。
必须对正反两面都加:
.front, .back {
backface-visibility: hidden;
}
漏掉任意一面,iOS 下都可能出现半透明残影、文字重影或翻转卡在 90°。Android Chrome 通常不报错,但统一加上更稳妥。
数字翻牌要支持非连续变化(比如从 5 直接到 9),得拆解个位/十位分别控制
如果直接对整个数字字符串做翻牌,5→9 这种单步变化没问题,但 19→20 就会出问题:你不能让“9”翻成“0”同时“1”翻成“2”,必须按位分离、独立触发翻牌动画,否则视觉错乱。
实操建议:
- 把数字转成字符串,用
split('')拆成数组,每位生成一个<div class="digit"> - 比对新旧数字字符串,仅对发生变化的位执行
add('is-flipped') - 为避免 0→1→2 连续翻造成视觉轰炸,加防抖:两次翻牌间隔至少
300ms - 补零逻辑(如显示
05)要在 JS 层处理好,不要靠 CSStext-align对齐数字位
真正难的不是让牌翻起来,而是让多位数字翻得准、不打架、不丢帧——尤其是用户快速滚动或频繁刷新时,DOM 更新和 class 切换的时机稍有偏差,翻牌就会卡住或错位。


















