TIL 项目实战:用 CSS Animation 打造平滑脉动背景动画

原创2026-10-03 12:12:22278 阅读
文章标签:文档教程知识库

TIL 项目实战:用 CSS Animation 打造平滑脉动背景动画

导读

在 TIL 项目("Today I Learned" 系列笔记,见 README.md)的 CSS 分类中,记录了如何仅用 @keyframes 关键帧规则加 animation 简写属性,实现一个无需 JavaScript、平滑循环的脉动背景效果。本文以 css/create-a-pulsing-background-with-css-animation.md 为骨架,系统讲解关键帧定义、动画属性调优、缓动与时长选择,并结合仓库中同主题笔记 css/animate-smoothly-between-two-background-colors.md 与 CSS 性能实践,给出可直接复制运行的完整方案。

一、效果原理:一段代码看懂脉动背景

脉动背景(pulsing background)的本质是:让元素的 background-color 在一个起始颜色与另一个颜色之间往复过渡。整个过程完全由浏览器渲染引擎驱动,CSS 只需声明"什么时刻是什么颜色",其余插值计算交给引擎完成。

原文档给出的核心关键帧规则如下:

@keyframes pulse {
  0%, 100% {
    background-color: #f56a3f;
  }
  50% {
    background-color: #9e42b0;
  }
}

关键点拆解:

  • @keyframes pulse:定义一个名为 pulse 的关键帧动画,名字可自由命名,后续通过 animation 属性引用;
  • 0%, 100%:动画起点与终点合并声明,background-color 为 #f56a3f(暖橙色);
  • 50%:动画进行到一半时颜色切换为 #9e42b0(紫色)。

浏览器会在 0% → 50% → 100% 三个关键帧之间自动插值,产生颜色渐变,而非生硬跳变。

二、应用到元素:animation 简写属性

定义好 @keyframes 后,需要把它挂载到目标元素上。原文档将它应用到 body,并配合无限循环与长时长:

body {
  animation: pulse 20s infinite;
}

这一行是 animation 简写属性,它按顺序展开为多个子属性:

简写中的位置 对应子属性 本例取值 说明
1 animation-name pulse 引用 @keyframes 名字,必须一致
2 animation-duration 20s 单个动画周期时长,越长越舒缓
3 animation-iteration-count infinite 无限循环;也可写具体次数如 3

仓库中同主题笔记 css/animate-smoothly-between-two-background-colors.md 展示了一个更精细的写法:将 0% 与 100% 分开声明、并把动画应用在带尺寸的类上:

@keyframes pulse {
  0% {
    background-color: red;
  }
  50% {
    background-color: blue;
  }
  100% {
    background-color: red;
  }
}

.square1 {
  animation: pulse 2s infinite;
  width: 100px;
  height: 100px;
}

两种写法等价:0%, 100% 合并声明与分开声明效果相同。区别在于应用范围——应用到 body 影响整页背景,应用到 .square1 这类带尺寸的元素则只影响该元素,适合做按钮、卡片、提示气泡等局部动效。

三、让"脉冲"真正平滑:时长、缓动与循环

原文档强调"以较长的时长无限循环,以获得真正的平滑手感"。这背后的可调旋钮有三个:

1. 时长(animation-duration)

  • 2s 左右:节奏较快,适合小元素上的注意力吸引;
  • 10s~20s:原文档采用的区间,颜色变化极其缓慢,视觉上"呼吸感"强,适合页面整体背景;
  • 配合 0% 与 100% 颜色相同的特点,循环接缝处无色差,肉眼几乎无法察觉动画重新开始。

2. 缓动(animation-timing-function)

默认缓动为 ease。想让颜色变化全程匀速,可显式指定:

body {
  animation: pulse 20s infinite ease-in-out;
}
  • ease-in-out:两头慢、中间快,模拟呼吸的起落感;
  • linear:全程匀速,适合色彩渐变的匀速呼吸灯;
  • steps(n):阶梯式跳变,若想要"离散切换颜色"而非平滑渐变,可以用它代替默认插值。

3. 循环次数

infinite 表示无限循环。若只想让"脉冲"发生固定几次再停下,替换为具体数值即可,例如 animation: pulse 2s 3;(3 次后停在 100% 关键帧状态)。

四、进阶:从固定颜色到自定义变量

写死两个十六进制色值虽然直观,但在大型项目中维护不便。可以将颜色抽成 CSS 自定义属性,让动画规则与配色解耦:

:root {
  --pulse-start: #f56a3f;
  --pulse-end: #9e42b0;
}

@keyframes pulse {
  0%, 100% {
    background-color: var(--pulse-start);
  }
  50% {
    background-color: var(--pulse-end);
  }
}

修改配色时只需更新 :root 中的两个变量,动画本身无需改动。这一思路与仓库中 css/define-css-custom-properties-with-scss-variables.md 记录的自定义属性实践一脉相承。

五、性能与可访问性注意点

1. 动效属性选择

background-color 属于 paint 类属性,在动画期间浏览器需要持续重绘元素区域。单元素、低频次(如 20s 一个周期)的脉动背景在现代浏览器上开销可忽略;但若在大量元素上高频动画 background-color,则可能造成掉帧。仓库中的 css/filter-blur-requires-expensive-calculation.md 记录了同类教训:昂贵的 CSS 效果在"数量多"的场景下会显著拖累渲染。若需要高性能方案,可考虑用 opacity 叠加静态渐变层来模拟呼吸效果,因为 opacity 属于合成器(compositor)友好的属性,动画更省资源。

2. 尊重用户偏好

对某些用户而言,持续脉动的动画可能引发不适。建议在实现中加入 prefers-reduced-motion 媒体查询降级处理:

body {
  animation: pulse 20s infinite;
}

@media (prefers-reduced-motion: reduce) {
  body {
    animation: none;
    background-color: #f56a3f;
  }
}

当用户在系统中开启"减少动态效果"时,动画被关闭、退回静态底色。仓库中 css/apply-styles-based-on-dark-mode-preferences.md 展示了同类媒体查询(prefers-color-scheme)的用法,二者语法一致,可以对照学习。

六、完整可运行示例

综合以上要点,给出一个完整示例,可直接放入 HTML 的 <style> 或独立 CSS 文件中:

:root {
  --pulse-start: #f56a3f;
  --pulse-end: #9e42b0;
}

@keyframes pulse {
  0%, 100% {
    background-color: var(--pulse-start);
  }
  50% {
    background-color: var(--pulse-end);
  }
}

body {
  /* 名称 时长 缓动 循环次数 */
  animation: pulse 20s ease-in-out infinite;
  min-height: 100vh;
}

@media (prefers-reduced-motion: reduce) {
  body {
    animation: none;
    background-color: var(--pulse-start);
  }
}

小结

通过 @keyframes 定义起点与终点关键帧、再用 animation 简写属性(名称 + 时长 + 循环次数)挂载到目标元素,即可在十几行 CSS 内得到平滑的无限脉动背景。微调时长与缓动可以控制节奏,引入自定义属性和 prefers-reduced-motion 则让方案更易维护、更友好。本主题的原始记录见 css/create-a-pulsing-background-with-css-animation.md,可结合 css/animate-smoothly-between-two-background-colors.md 与 css/style-a-background-with-a-linear-gradient.md 继续延伸学习背景相关的其他技巧。

登录后查看全文
til