必须用双层包裹结构,正面背面同级且显式定义,.card需preserve-3d和transition,.front/.back须absolute定位并设backface-visibility:hidden,.back初始rotateY(180deg),移动端需JS切换is-flipped类。

直接用下面这套结构+样式就能跑起来,不用改路径、不依赖框架、兼容 Chrome/Firefox/Safari(含 iOS 16+)。
HTML 结构必须是双层包裹
单个 <img> 或只用一个 <div> 做翻转,永远翻不出背面——因为没第二面。必须有显式定义的正面和背面两个同级元素:
-
<div class="card-container">:设perspective,决定“你离卡片多远”,值太小(如200px)会夸张变形,太大(如5000px)就看不出深度,1000px是稳妥起点 -
<div class="card">:这是真正翻转的容器,必须加transform-style: preserve-3d,否则子元素退化成平面,翻转后像消失一样 -
<div class="front">和<div class="back">:必须position: absolute+top: 0; left: 0; width: 100%; height: 100%,否则翻转时错位或露白边
CSS 样式里这三行不能少
缺任意一条,翻转都会出问题:空白、闪烁、卡在 90°、文字镜像……
-
.card { transform-style: preserve-3d; transition: transform 0.6s ease; }:动画只作用于transform,别写all 0.6s,否则可能触发布局重排 -
.front, .back { backface-visibility: hidden; }:必须分别加在两面上,只加在.card上无效;iOS 微信 WebView 有时掉支持,可补-webkit-backface-visibility: hidden -
.back { transform: rotateY(180deg); }:背面初始就要翻过去,不然 hover 一触发,它会先“弹”一下再翻——这是最常被忽略的细节
移动端点击翻转必须用 JS 切类名
纯 :hover 在手机上基本不可用,:active 更不行(松手就回弹)。可靠做法是绑定 click 并切换 is-flipped 类:
立即学习“前端免费学习笔记(深入)”;
- HTML 中给
.card加tabindex="0",让它能被键盘聚焦,兼顾可访问性 - CSS 写
.card.is-flipped { transform: rotateY(180deg); },不要用!important覆盖 hover - JS 用
element.classList.toggle('is-flipped'),比setAttribute更轻量;连点多次易错乱,可在transitionstart临时加pointer-events: none
图片模糊或边缘锯齿?优先检查这两处
不是图本身质量差,而是渲染层没提上去:
- 给
.card加will-change: transform(仅在必要时加,别全局滥用) - 如果背面是背景图,确保
background-size: cover+background-position: center,否则高 DPI 屏上拉伸失真 - 别用
z-index控制正反面顺序——3D 空间里它无效,靠的是translateZ()值和rotateY()组合
最易被忽略的其实是 .back 的初始 transform: rotateY(180deg)。很多人只写 hover 动画,忘了背面得预先“摆好位置”,否则第一帧会抽搐。这点在调试时肉眼难察觉,但用户点第一次就会觉得卡顿。



















