纯 CSS 打字机动画必须用 width + steps(n, end) + overflow: hidden + 等宽字体;steps 第二参数 end 防止首帧空白,n 必须等于字符数,ch 单位更稳,需配合 white-space: nowrap 和 inline-block,光标推荐 border-right + step-end 闪烁。

纯 CSS 实现打字机动画,关键不是“让文字动”,而是**用 width 动画 + steps() 切帧 + overflow: hidden 配合等宽字体**,让浏览器一帧一帧地“露”出字符。其他写法(比如试图动画 ::after 的 content)根本无效。
为什么 steps(n, end) 是必须的,而不是 steps(n)
CSS 的 steps() 第二个参数不写,默认行为因浏览器而异:Chrome 会 fallback 到 start,Firefox 可能按 end 处理。写死 steps(10, end) 才能确保第 0 帧显示 0 字符、第 1 帧显示第 1 字、……第 10 帧显示全部 10 字。漏掉 end,开头大概率空一帧,第一字延迟出现。
常见错误现象:animation: typing 2s steps(10); 在 Safari 下第一字卡顿半秒才出来 —— 就是这个原因。
-
n必须等于文本字符数(中文、英文、标点、空格都算 1) - 用
ch单位比用%或em更稳,因为1ch ≈ 当前字体下 "0" 的宽度,天然适配等宽字体 - 动画时长建议 ≥
0.05s × n;n=20时,至少设1s,否则人眼跟不上
width 动画为何要配合 overflow: hidden 和 white-space: nowrap
width 本身不会“裁剪”文字 —— 它只控制容器宽度。真正挡住多余文字的是 overflow: hidden;而 white-space: nowrap 防止空格或连字符触发换行,破坏逐字节奏。
立即学习“前端免费学习笔记(深入)”;
容易踩的坑:
- 忘了设
display: inline-block或inline-flex——width对默认display: inline元素无效 - 用了非等宽字体(如
system-ui),但还按ch算宽度 —— 中文和英文字符宽度不一致,导致“多露”或“少露” - 父容器宽度变化(比如响应式布局中
max-width改变),但动画终点仍写100%—— 实际宽度错乱,打字跳步
光标闪烁该用 border-right 还是 ::after?
::after 只适合做静态光标(比如方块、竖线),但**不能用来驱动打字逻辑**;它的 content 属性不可动画,强行写 animation: cursor 1s infinite 对 content 没效果。
推荐用 border-right 实现光标:
- 加在同一个元素上,不用额外 DOM 节点
- 用
@keyframes blink { from { border-color: transparent; } to { border-color: currentColor; } }+animation: blink 0.75s step-end infinite -
step-end确保光标是“瞬间亮/灭”,不是渐变,更像真实键盘光标 - 如果要用自定义形状(如 ▌),再叠加
::after,但仅控制opacity或transform,别碰content
最常被忽略的一点:**字符数变了,steps() 的 n 和动画时长就得同步改**。静态文本可以手写,但动态内容(比如从 API 拉的文案)必须用 JS 注入 CSS 变量,否则要么卡顿要么漏字 —— 这不是 CSS 能自动感知的事。


















