翻转动画需同时满足三个条件:父元素设transform-style: preserve-3d、设置perspective(推荐在.card上)、背面元素加backface-visibility: hidden;用data-state驱动变量映射而非直接calc();transition必须写在执行rotateY()的子元素上。

翻转动画不触发?检查 transform-style 和 perspective
纯靠 --rotate-y 变量控制 rotateY() 是行不通的——CSS 变量不能直接注入到 transform 函数里参与计算,浏览器不支持表达式求值。真正起作用的是用变量控制「是否翻转」的状态,再配合预设的 transform 组合实现。关键前提是:父容器必须设置 transform-style: preserve-3d,且自身或祖先需有 perspective(比如 perspective: 1000px),否则翻转会扁平化、无立体感。
-
perspective建议写在卡片容器(如.card)上,而非:root,避免影响其他元素 -
transform-style: preserve-3d必须加在翻转的直接父元素(通常是.card-inner或.card)上 - 若翻转后背面内容不可见,大概率是背面元素没加
backface-visibility: hidden
用 :is() + data-state 驱动变量切换更可靠
别用 :hover 直接改 rotateY(180deg)——它无法与 CSS 变量联动。推荐用 HTML 属性驱动:data-state="flipped",再用属性选择器配合 style 中的变量声明做状态映射。这样既可 JS 控制(el.dataset.state = "flipped"),也方便后续加动画逻辑。
- 在
:root或组件作用域定义:--rotate-y: 0deg(默认)和--rotate-y-flipped: 180deg - 用
.card[data-state="flipped"] .card-front { transform: rotateY(var(--rotate-y-flipped)); }显式绑定 - 避免用
calc()动态算角度——CSS 不支持calc(var(--rotate-y))这种写法
transition 必须写在被旋转的元素上,且指定 transform
很多人把 transition: transform 0.4s ease 写在父容器,结果动画不生效。翻转动画的本质是子元素的 transform 变化,所以过渡必须落在执行 rotateY() 的那个元素(比如 .card-front 和 .card-back)上。
- 两个面都要加
transition: transform 0.4s ease,否则只有一面动 - 不要写成
transition: all 0.4s,性能差且可能触发重排 - 若想翻转更真实,可给
.card-back加transform: rotateY(-180deg)初始态,再通过状态切到0deg
移动端点击翻转要防误触,得加 cursor: pointer 和 touch-action
单纯绑 click 在 iOS 上可能延迟 300ms,且滑动时容易误触发。CSS 层面至少做两件事:让卡片可点击感知,同时禁用默认手势干扰。
立即学习“前端免费学习笔记(深入)”;
- 给卡片加
cursor: pointer(哪怕非 hover 场景也建议加) - 加
touch-action: manipulation,告诉浏览器「这是可点击区域,别等双击或缩放」 - JS 触发翻转时,优先用
classList.toggle("flipped")而非反复 set/dataset,避免竞态
transform 声明、以及 3D 渲染上下文是否就绪——这两点漏掉任何一项,翻转都会静默失败。


















