CSS 变换实战:用 transform 做出顺滑动效
讲清 CSS transform 的 translate、rotate、scale、skew 四个通道,2D 与 3D 的差别,transform-origin 怎么用,再配 transition 做出顺滑的 hover 动效,附一段可直接复制的 CSS。
CSS 变换实战:用 transform 做出顺滑动效
写动效这几年,我踩过最多的坑都跟 transform 有关。要么是 3D 翻转出来是个压扁的矩形,要么是 hover 放大在便宜手机上卡成幻灯片。其实 transform 本身不复杂,真正难的是把 translate、rotate、scale、skew 这四个通道、2D 和 3D 的差别、transform-origin 的落点,再加上 transition 的缓动,这几件事一次性想清楚。这篇就按我实际用它的顺序讲一遍。
四个通道:translate、rotate、scale、skew
transform 接受一串函数,常用的就四类。translate(40px, 0) 是平移,把元素沿 X、Y 轴搬走,不影响布局,周围的兄弟节点不会跟着挪。rotate(45deg) 是旋转,默认绕元素中心转。scale(1.5) 是缩放,等比例放大 1.5 倍;只想动一个轴就写 scaleX(1.5)。skew(12deg, 0) 是斜切,把矩形拉成平行四边形,做标签和倾斜卡片很顺手。
这四个能组合:transform: translateX(40px) rotate(15deg) scale(1.1);。但要记住一件反直觉的事,顺序会改结果。CSS 是从右往左转成矩阵相乘,矩阵相乘不满足交换律。translate(100px) rotate(45deg) 是先平移再绕新原点转;rotate(45deg) translate(100px) 是先转再沿旋转后的轴平移,元素会跑到大约 (71, 71) 像素的位置,完全不是一回事。规范顺序一般是 perspective → translate → rotate → scale → skew,跟主流动画库对齐,够用 95% 的场景。
2D 与 3D:perspective 不能省
2D 就是上面四个。3D 多了 rotateX、rotateY、rotateZ、translateZ,以及关键的 perspective。新手最常犯的错就是写了 rotateX(60deg) 却忘了 perspective,结果出来是个被水平压扁的矩形。浏览器其实算了 3D 变换,但你看到的是正交投影,没有"远小近大"的深度提示。
perspective(800px) 的意思是"把元素当作观察者眼睛距屏幕 800 像素来渲染"。值越小鱼眼越夸张,200 到 400px 很戏剧化;值越大越接近轻微倾斜,1500px 以上几乎平。卡片翻转用 800px 是行业默认,正好适配 200 到 400px 宽的卡片;全屏 hero 区调到 1200 到 1500px,透视感才不显得卡通。
transform-origin:绕哪个点变
所有变换都有一个支点,默认是元素中心 50% 50%。transform-origin 就是改这个支点。把它设成 0 0,旋转就绕左上角转;设成 100% 100% 就绕右下角。做菜单从角上展开、做指针绕底端摆动,都靠它。我自己调翻转时,翻得不对劲十有八九是 origin 被无意中设成了 0 0,改回默认 50% 50% 就正了。
配 transition 做动效
光有 transform 是瞬间跳变,加上 transition 才有过渡。transition: transform 0.4s ease-out; 表示这个元素的 transform 一旦变化就用 0.4s 完成。:hover 时过渡到 hover 态,鼠标移开时也用 0.4s 回去。想要进快出慢,就写两条:基础态一份管离开,:hover 里再覆盖一份管进入。
为什么坚持用 transform 而不是改 left / width?因为 transform 走 GPU 合成,不触发布局也不触发重绘。改 left、top 每帧都重排,改 width、height 连子节点都要跟着排,复杂页面一帧能吃 5 到 20ms,60fps 直接掉到 20fps。能用 translate / rotate / scale / skew 表达的运动就用 transform,视觉一样,CPU 开销少 80% 以上。
一段能直接抄的卡片翻转
下面是我常用的卡片翻转,贴进去就能跑:
.card {
transform-origin: 50% 50%;
transition: transform 0.4s ease-out;
}
.card:hover {
transform: perspective(800px) rotateY(180deg) scale(1.02);
}
perspective(800px) 给深度,rotateY(180deg) 翻面,scale(1.02) 让翻转时微微抬一下更有立体感。手写这段要反复试 perspective 值和缓动,用生成器边拖边看实时预览,十秒就能定下来。可以直接打开 /zh/t/css-transform-generator/ 拖滑块,套内置的 card-flip 预设,复制整段 .box 代码块,transform-origin 和 transition 都帮你接好了。
做卡片或按钮时,翻转动效配上一点投影会更有层次,这步可以顺手用 /zh/t/box-shadow-generator/ 生成阴影叠上去,两个工具配合,一张能 hover 翻面、带投影的卡片几分钟就成型。
Made by Toolora · Updated 2026-06-13