Springs and Bounces in Native CSS
来源: joshwcomeau.com/animation/linear-timing-function/
内容概述
本文深入探讨了 CSS 的 linear() timing function,这是一个革命性的新特性,允许开发者使用离散的点来模拟任意 easing 曲线,从而实现弹簧和弹跳效果,而无需依赖 JavaScript 动画库。
关键亮点
1. linear() 函数的核心概念
- 不是使用数学推导的 Bézier 曲线,而是通过指定 Cartesian 平面上的离散点来绘制 easing 曲线
- 看起来像曲线,实际上是一组直线段连接的"连接点"图形
- 函数接受一组数字,0 代表起始值,1 代表最终值
示例代码:
.block {
transition: transform 500ms linear(0, 0.1, 0.25, 0.5, 0.68, 0.8, 0.88, 0.94, 0.98, 0.995, 1);
}
2. 模拟弹簧物理
- 11个点不够模拟弹簧 - 元素会机械地在离散点之间移动
- 50+个点才能产生令人信服的弹簧效果
- 像 Bézier 曲线一样,linear() 允许选择 0-1 范围之外的值来 overshoot 目标
3. 推荐工具
- Linear() Easing Generator (Jake Archibald & Adam Argyle) - 预装了将弹簧参数转换为 linear() 字符串所需的数学计算
- Easing Wizard - 最全面的工具,使用 linear() 模拟弹簧、弹跳、摆动等
4. 高级语法
.thing {
transition: transform 1500ms linear(
0,
0.013 0.6%,
0.05 1.2%,
0.2 2.5%,
/* 更多点... */
0.971 47.2%,
1.012 59.1%,
0.995 70.8%,
1
);
}
5. 局限性
- 仍然是基于时间的 - 需要指定持续时间,无法像 JavaScript 库那样使用 stiffness、damping、mass 等物理属性
- 中断处理 - CSS 版本会立即掉头,而 React Spring 等库会考虑当前惯性
- 性能 - 75个点的 linear() 只增加约 1.3kB CSS (gzip),在 3G 连接下只需 5ms 下载
6. 最佳实践
- 使用 CSS 变量存储常见的 timing functions
- 使用 @supports 提供 Bézier 曲线回退方案
- 使用 prefers-reduced-motion 尊重用户的运动偏好
完整示例:
html {
--spring-smooth: cubic-bezier(...);
--spring-smooth-time: 1000ms;
@supports (animation-timing-function: linear(0, 1)) {
/* stiffness: 235, damping: 10 */
--spring-smooth: linear(...);
}
}
@media (prefers-reduced-motion: no-preference) {
.thing {
transition: transform var(--spring-smooth) var(--spring-smooth-time);
}
}
总结
linear() 函数是一个可爱的 API,极大地扩展了原生 CSS 的能力。它可以让我们用纯 CSS 创建弹簧和弹跳效果,替代传统的 JavaScript 动画库。虽然有一些局限性(主要是基于时间和中断处理),但对于大多数用例来说,这是一个值得采用的现代 CSS 特性。
探索日期: 2026-03-17 | 来源: Josh W. Comeau