steps()是必须的,因为它将动画切成离散步,实现逐字显现;而cubic-bezier()或linear会导致连续插值,造成字符模糊、重叠或滑动效果。

纯 CSS 能做出可用的打字机动画,但必须用 steps() 控制节奏,否则文字会“滑”出来,不是逐字显现。
为什么 steps() 是必须的
默认的 cubic-bezier() 或 linear 会让 width 或 transform 连续插值,导致字符模糊、重叠或跳变;steps(N, end) 把动画切成 N 个离散步,每步只显示前 N 个字符,这才是真实打字节奏。
-
steps(1, end)表示整段动画只跳变一次,且发生在最后一帧——这不是你要的效果 -
steps(6, end)才对应 6 字文本(含空格),N 必须等于textContent.length - 漏写
end参数(比如只写steps(6))会导致部分浏览器 fallback 到start,第一帧就全显或闪一下再开始
width + ch 单位是最简可靠方案
适合单行、内容固定场景,IE10+ 兼容,但依赖字体宽度一致性。
- 容器必须设
white-space: nowrap,否则空格或长单词会提前折行,破坏ch计算 - 用
ch比em或像素更稳——它基于当前字体中"0"的宽度,等宽字体下天然对齐字符边界 - 动画终点写成
width: calc(var(--char-count) * 1ch),而不是100%,避免父容器缩放影响 - JS 动态注入变量:
el.style.setProperty('--char-count', el.textContent.length)
中英文混排时 ch 失效怎么办
多数中文字体里,“中”和“0”的宽度不等,一个汉字可能占 1–2 个 ch,直接套用会截断或留白。
- 改用
transform: scaleX(0) → scaleX(1),配合overflow: hidden和display: inline-block - 子元素加
transform-origin: left,确保从左往右展开 -
steps()的 N 仍要手动数字符数,但视觉节奏更稳定 - 如果必须用 width,可临时切到
font-family: monospace,或 JS 测出平均字符宽度再计算
光标闪烁不同步是最高频翻车点
光标动画和打字动画用不同 timing function,一眼就能看出脱节。
- 光标必须共用同一
animation-timing-function:比如打字用steps(12, end),光标就得用blink 0.75s step-end infinite - 别用
border-right配ease,那会像呼吸灯,不是打字机光标 - 低性能设备上,
width动画触发布局重排,比transform卡;加will-change: transform也没用,得换方案
真正难的不是写出第一版效果,而是让中英文混排不崩、多行错开不抢拍、光标不飘、字体加载延迟后仍准——这些细节没被显式处理时,上线就露馅。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











