steps()函数通过steps(n, end)实现逐字跳显动画,需配合width: 0ch→nch、等宽字体、white-space: nowrap及避免折行干扰,禁用%或em单位,注意ie不支持及layout性能问题。

steps() 函数怎么让打字动画不滑动、一格一格跳?
因为 steps() 不是缓动函数,它强制把动画过程切成固定份数,每份之间不插值——所以文字不是“慢慢出现”,而是一次显示一个字符(或几个字符),像老式电报机那样“嗒、嗒、嗒”。关键在第二参数:steps(5, end) 和 steps(5, start) 行为完全不同。
-
end(默认):每步结束时才更新显示,第 0 帧空白,第 1 步显示前 1/5,第 2 步显示前 2/5……最后一帧才完整 -
start:每步开始时就更新,第 0 帧就显示前 1/5,容易导致首帧“多出一截”,慎用 - 字符数必须和
steps()第一参数对齐,否则末尾会卡住或提前结束——比如 12 个字符,用steps(12)最稳
如何用 ch 单位 + width 模拟逐字显示?
本质是遮罩:用 overflow: hidden 容器包住文字,再通过 width 从 0ch 动画到 Nch(N 是字符数),配合 steps(N) 实现离散展开。注意 ch 单位依赖等宽字体,非等宽字体下会错位。
- 必须设
font-family: monospace或明确指定等宽字体,比如font-family: 'SFMono-Regular', Consolas, monospace -
width动画需作用在子元素上(如<span></span>),不能直接 animating<p></p>的 width,否则可能触发重排 - 别用
%或em替代ch——它们不按字符数线性映射,steps()就会失准
span { display: inline-block; width: 0ch; animation: type 2s steps(15, end) forwards; } @keyframes type { to { width: 15ch; } }
为什么加了 white-space: nowrap 还换行?
常见于容器宽度不够或父级有 word-break: break-word 等干扰样式。打字动画依赖单行连续渲染,一旦折行,ch 计算就失效,steps() 显示节奏全乱。
- 检查直接父容器是否设置了
max-width或flex限制,临时加min-width: max-content测试 - 确认没继承到
word-wrap: break-word或overflow-wrap: break-word,这两个会主动拆单词 - 移动端要注意 viewport 缩放或
text-size-adjust导致字体实际宽度变化,影响ch精度
兼容性与性能要注意什么?
steps() 在所有现代浏览器都支持,但 IE 完全不支持;动画本身用 width 属于触发 layout 的属性,高频使用可能掉帧。
立即学习“前端免费学习笔记(深入)”;
- 避免在长列表项里批量用这个效果——每个都要独立计算
ch宽度,且 layout 开销叠加 - 真要兼容 IE?只能退化为 js 控制
textContent截取,用setTimeout模拟节奏,css 方案直接降级为无动画 -
ch单位在 safari 旧版本(font-size: 1rem 锁定基准
事情说清了就结束。最常被忽略的是:字符数和 steps() 参数必须严格一致,以及 ch 对字体的强依赖——换个字体,整个节奏就偏了。