Springs and Bounces in Native CSS

CSS Animation ⭐⭐⭐⭐⭐ 5星

来源: 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