CSS 动画在 TIL 仓库中的平滑背景色过渡:@keyframes 从原理到实战
CSS 动画在 TIL 仓库中的平滑背景色过渡:@keyframes 从原理到实战
导读
本文以 TIL 仓库中的 animate-smoothly-between-two-background-colors.md 为骨架,系统讲解如何用 CSS @keyframes 动画实现两个背景色之间的平滑过渡。你将掌握关键帧规则的编写、animation 简写属性的运用,以及如何将其扩展为无限循环的脉冲呼吸效果,并理解浏览器渲染引擎在背后执行插值运算的原理。
核心思路:把"颜色变化"交给渲染引擎
CSS 动画的价值在于:你只需要定义规则(起点、终点、中间关键状态),剩下的中间过程全部由浏览器的渲染引擎自动插值完成。换句话说,你描述的是"状态",而不是"过程"——引擎会根据时间轴自动算出每一帧该显示什么颜色。
这一点在仓库的 create-a-pulsing-background-with-css-animation.md 中有同样清晰的表述:开发者只需声明起始与结束颜色,中间的一切交给浏览器。
第一步:定义 @keyframes 动画规则
在 animate-smoothly-between-two-background-colors.md 中,作者创建了一个名为 pulse 的 @keyframes 规则:
@keyframes pulse {
0% {
background-color: red;
}
50% {
background-color: blue;
}
100% {
background-color: red;
}
}
关键点解读:
- 百分比是时间轴坐标:
0%表示动画开始时刻,100%表示动画结束时刻,50%表示动画进行到一半。 - 中间帧自动插值:从
0%的红色到50%的蓝色,再到100%回到红色,两个区间的过渡全部由引擎计算生成,无需逐帧编写。 - 名字自取:
pulse(脉冲)只是一个语义化名称,你完全可以命名为fade、blink等,只要与后续animation属性中的名字保持一致。
在单次动画周期内,该规则的行为是:背景色从红色开始,到动画 50% 处过渡为蓝色,最后再回到红色——形成一次"红→蓝→红"的往返。
第二步:把动画应用到元素上
定义好规则后,可以通过 animation 属性把它挂载到任意 CSS 类上(原文代码):
.square1 {
animation: pulse 2s infinite;
width: 100px;
height: 100px;
}
animation 是简写属性,这里依次指定了:
| 参数 | 值 | 含义 |
|---|---|---|
| 动画名称 | pulse |
对应上方 @keyframes pulse 规则 |
| 持续时间 | 2s |
完成一个完整周期用时 2 秒 |
| 循环次数 | infinite |
无限循环播放 |
任何带有 square1 类的元素,都会拥有 100px × 100px 的尺寸,并持续播放背景色脉冲动画。
延伸实战:合并关键帧实现"呼吸脉冲"
仓库中的姊妹篇 create-a-pulsing-background-with-css-animation.md 展示了更简洁的写法——把首尾相同的帧合并:
@keyframes pulse {
0%, 100% {
background-color: #f56a3f;
}
50% {
background-color: #9e42b0;
}
}
0%, 100%合并声明:动画开始与结束时颜色相同,均为#f56a3f。50%时过渡到#9e42b0,引擎自动补全中间的所有过渡帧。
应用方式也与之呼应:
body {
animation: pulse 20s infinite;
}
把持续时间拉长到 20s,配合 infinite 无限循环,就能得到非常舒缓、自然的"呼吸"式背景变化——这也是 TIL 仓库中展示的最具代表性的实战形态。相比 2s 的快节奏脉冲,20s 更适合作为整页背景的氛围效果。
关键帧与渐变的关系:理解"颜色过渡"的两种手段
同样是"从一种颜色平滑到另一种颜色",仓库中的 style-a-background-with-a-linear-gradient.md 给出了另一条路径——线性渐变:
.container {
background: linear-gradient(#00449e, #e66465);
}
两者本质区别在于:
linear-gradient:在空间维度上做颜色插值,两个颜色在同一时刻存在于元素的不同区域,形成渐变带。@keyframes动画:在时间维度上做颜色插值,元素在某一时刻只显示一种颜色,颜色随时间推移而变化。
理解这一区分,能帮你在设计时做出正确选择:需要"整块背景随时间变色"用动画,需要"同一块背景呈现渐变"用渐变函数。
进阶要点与注意事项
结合 TIL 仓库中的相关实践,以下几个要点值得在实际项目中注意:
- 动画名一致性:
@keyframes的名字必须与animation简写属性中的第一个值完全一致,拼写错误会导致动画静默失效。 - 用十六进制颜色代替命名色:命名色(如
red、blue)在多数浏览器中可用,但使用十六进制或 HSL 值(如#f56a3f)语义更精确,也便于团队统一管理。 - 适当拉长时长获得平滑感:如姊妹篇所示,
20s这类长周期配合infinite,比短周期更能营造自然平滑的视觉体验,尤其适合作为页面背景。 - 可与自定义属性联动:仓库中的 define-css-custom-properties-with-scss-variables.md 展示了使用 CSS 自定义属性管理颜色的实践,你可以把关键帧中的色值抽成变量,实现主题化动画。
- 注意无障碍体验:长时间高频闪烁的动画可能对光敏性用户不友好。如需在生产环境使用,可考虑结合
prefers-reduced-motion媒体查询(见仓库中的媒体查询实践 apply-styles-based-on-dark-mode-preferences.md)在用户偏好减少动效时关闭或放慢动画。
小结
通过 TIL 仓库这份笔记,我们完成了从"定义关键帧规则"到"应用动画属性"再到"实战变体"的完整闭环:
@keyframes用百分比描述时间轴上的颜色状态;- 渲染引擎自动完成状态之间的插值过渡;
animation: pulse 2s infinite一行即可挂载并循环播放;- 合并首尾帧、拉长时长,即可得到优雅的呼吸脉冲效果。
这套"定义状态、引擎插值"的模型不仅适用于背景色,同样可以推广到 opacity、transform、filter 等可动画属性,是 CSS 动画体系的基础功。