CSS 过渡与变换
静态页面看多了难免单调。今天开始给页面加点动效。CSS 的动效家族有两个基础成员,过渡 transition 和变换 transform。过渡负责”怎么变过去”,变换负责”变成什么样子”,两者经常配合使用。
过渡,状态变化之间的动画
回想一下CSS 伪类里学过的 :hover。鼠标悬停时样式瞬间切换,生硬又突然。过渡的作用就是给这个切换过程加一段平滑动画。
transition 有四个子属性:
| 子属性 | 作用 | 注意事项 |
|---|---|---|
| transition-property | 指定对哪些属性做过渡 | 默认 all,范围越窄性能越好 |
| transition-duration | 过渡持续时长 | 必填,不写就没有动画 |
| transition-timing-function | 速度曲线 | 常用 ease、linear、ease-in-out |
| transition-delay | 延迟多久开始 | 日常少用,别乱加 |
最常用的简写写法:
.button {
background: #4a90d9;
transition: all 0.3s;
}
.button:hover {
background: #3a78b8;
}
只要 0.3s,背景色就平滑地渐变过去。注意一个概念,过渡本身不产生动画,它只描述状态之间的过程。触发条件是目标元素被应用了新的样式状态,最常见的就是 :hover 和 :focus 切换。
变换,位移旋转缩放倾斜
transform 可以改变元素的样子,有四个基础函数,每个都写一行示例:
/* 位移,向右下各移动 20px */
.box { transform: translate(20px, 20px); }
/* 旋转,顺时针转 45 度 */
.box { transform: rotate(45deg); }
/* 缩放,放大 1.5 倍 */
.box { transform: scale(1.5); }
/* 倾斜,像被推歪的平行四边形 */
.box { transform: skew(10deg); }
transform 有个重要特性,它不影响文档流。元素被放大或移动后,周围的元素完全不动,不会像改 margin 那样把布局挤开。这既是优点也是隐患,元素可能盖住别的内容,需要心里有数。另外 rotate 默认绕着元素中心转,想改旋转点可以用 transform-origin 指定,比如 transform-origin: left top 让元素绕左上角转,日常用得不多,知道即可。
多个变换组合时的顺序
transform 可以一次写多个函数,空格隔开:
.box {
transform: translate(50px, 0) rotate(45deg);
}
这里有个反直觉的规则,后写的先应用。上面的代码先旋转后位移。如果反过来写成 rotate 在前 translate 在后,是先位移再旋转,而旋转会带偏坐标系,位移方向就变了。想保持”先挪位置再旋转”的直觉,就把 translate 放在前面。
两个容易踩的坑
第一个坑,过渡对 display 无效。display 不是可插值的属性,值之间没有中间态,display: none 切到 block 只能瞬间切换,没有动画可做。想实现展开收起效果,可以用 visibility 和 opacity 配合,或者用 max-height 技巧。
第二个坑,对不可插值的属性无效。过渡要求属性值能连续变化,颜色、长度、透明度都可以,但像 font-family 这种离散值就不行,它没有中间状态可算。
性能提示
动画属性不是生而平等的。改 width、height、margin 这些属性,浏览器每帧都要重新计算布局,页面容易卡顿。而 transform 和 opacity 可以交给 GPU 处理,开销小得多。经验法则是,动效尽量用 transform 和 opacity 实现,比如用 scale 代替改 width,用 translate 代替改 top。
完整示例,按钮悬停动效
<button class="btn">点我试试</button>
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
background: #4a90d9;
color: #fff;
font-size: 16px;
cursor: pointer;
transition: transform 0.3s, box-shadow 0.3s;
}
.btn:hover {
transform: translateY(-4px) scale(1.05); /* 上浮并轻微放大 */
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
悬停时按钮轻轻上浮,带出阴影,松开后恢复原样。短短两行过渡,页面质感立刻不一样。
小结
过渡和变换是动效的地基。过渡负责状态之间的平滑变化,变换负责位移、旋转、缩放、倾斜这些几何操作。记住三点,变换不影响文档流,组合变换时 translate 放前面,动效优先用 transform 和 opacity。下一篇在此基础上讲动画 @keyframes,让元素自己动起来。