steps() 是唯一能可靠实现逐字节奏的 CSS 动画方式,需配合 width 或 clip-path、精确字符数、animation-fill-mode: forwards 等细节才能实现稳定打字效果。

steps() 是唯一能可靠实现逐字节奏的 CSS 动画控制方式,其他线性缓动(linear、cubic-bezier)都会让文字“滑”出来,失去敲击感。
用 width + steps() 实现单行打字效果
这是最轻量、兼容性最好的方案,但要求字体等宽或用 ch 单位校准宽度。
-
white-space: nowrap必须加,否则换行会打断动画序列 -
overflow: hidden是前提,否则文字直接全显 -
width动画起始为0,终点建议写具体值(如12ch),避免响应式下100%失效 -
steps(N, end)中的N必须等于字符总数(含空格、标点),JavaScript 可用textContent.length获取;中文/emoji 一般没问题,但组合字符要用Array.from(str).length - 动画时长建议按字符数动态设,比如
0.08s * N,太快看不清,太慢像卡顿
用 clip-path 支持任意字体和中英文混排
当必须用非等宽字体(如 "Helvetica Neue", sans-serif)或内容含 emoji 时,clip-path 更稳。
- 初始状态写
clip-path: inset(0 100% 0 0),即遮住全部右侧 - 终点写
clip-path: inset(0 0 0 0),完全露出 - 仍需配
steps(N, end),且N严格匹配字符数 - Safari 对
clip-path动画早期版本支持不一,iOS 15+ 和 Chrome 90+ 没问题 - 别用
inset(0 X% 0 0)中间插值——CSS 不允许百分比在steps()内插值,只认起点和终点
光标闪烁不能和打字动画耦合
光标是独立视觉元素,它的节奏和打字无关。强行同步反而容易在低端安卓 WebView 中掉帧或首帧闪动。
立即学习“前端免费学习笔记(深入)”;
- 推荐用
border-right:简洁、无需额外 DOM 节点,@keyframes blink-caret { 50% { border-color: currentColor; } } - 若用
::after,content: "|"需配合position: absolute和right: 0对齐末尾,且要设pointer-events: none - 闪烁周期 ≥ 0.5s,
animation-duration: 0.75s是较舒服的默认值 - 别给光标加
transform或font-size动画——它只该“亮/灭”,不该“缩放”或“偏移”
多行、动态内容或响应式场景必须交由 JS 控制
CSS 无法自动统计行数、无法监听文本变化、也无法根据容器宽度重算 steps() 数量。硬套纯 CSS 会漏字、卡住或错位。
- 用 JS 把字符串转成字符数组:
el.textContent.split('').map((c, i) => `<span style="animation-delay:${i * 80}ms">${c}</span>`).join('') - 每行单独包裹
<div class="line">,再分别设animation-delay错开起始时间 - 响应式下,监听
resize后重新计算字符数并注入 CSS 变量(如--char-count),再用steps(var(--char-count)) - 超过 50 字时,一次性生成大量
<span>可能引发重排,可考虑分批requestIdleCallback渲染
最容易被忽略的是:动画结束后文字消失,是因为漏了 animation-fill-mode: forwards;而光标没对齐末尾,往往是因为容器用了 vertical-align 或 line-height 不匹配导致基线偏移。


















