纯 CSS 打字机效果需用 width 动画配合 steps(字符数, end),文字写死+overflow: hidden 裁剪,强制等宽字体,width 从 0ch 到总字符数 ch,注意 display、父容器宽度及动画声明完整性。

如何用 width 动画 + steps() 实现打字机效果
纯 CSS 打字机效果的核心不是逐字显示,而是模拟“光标在固定宽度内逐格推进”的视觉错觉。关键在于用 width 控制可见区域,配合 steps() 让动画不平滑、不插值,形成卡顿式前进。
常见错误是直接对 content 做动画(不可能),或用 opacity + ch 单位过渡(浏览器支持差、精度低)。正确路径是:文字完整写死,用 overflow: hidden 配合 width 动画裁剪,再靠 steps(字符数, end) 分帧。
-
width动画起点必须是0ch,终点是完整文本的ch宽度(比如 12 个字符就设12ch) -
steps()的第一参数要严格等于字符数(含空格),少 1 就会漏最后一个字;end表示每步在时间结束时跳变,避免首帧空白 -
ch单位依赖等宽字体,必须显式设置font-family: monospace或具体等宽字体(如Consolas),否则1ch不准
为什么不能用 max-width 或 clip-path 替代 width
max-width 动画无法触发重排裁剪,浏览器不会按帧重新计算可见区域;clip-path 虽能裁剪,但 inset() 或 polygon() 配合 steps() 在 Safari 中表现不稳定,且无法精确对齐字符边界。
真实场景中,如果容器本身有 padding 或 border,width 必须配合 box-sizing: border-box,否则动画终点会偏移。另外,ch 在 Firefox 中对连字(ligature)处理异常,若文本含 fi、fl 等,建议加 font-variant-ligatures: none 关闭。
立即学习“前端免费学习笔记(深入)”;
- 用
width是唯一能在所有现代浏览器中稳定复现字符级步进的方式 - 避免在响应式布局中直接绑定
ch,若容器宽度变化,需用 JS 监听并重设动画终点(style.setProperty('--width-ch', len))
@keyframes 里写 width: 0ch → 12ch 但动画不动?检查这三点
最常踩的坑不是代码写错,而是上下文缺失。动画不触发往往因为元素没进入文档流,或被其他样式覆盖。
- 父容器必须有明确宽度(比如
width: 100%或固定值),否则width: 0ch无参照系 - 元素不能是
display: inline(默认),必须设为inline-block或block,否则width不生效 - 动画属性必须完整声明:
animation: typing 3s steps(12, end), cursor 1s infinite step-end—— 注意逗号分隔多个动画,且光标动画要用step-end避免闪烁
光标闪烁怎么和打字节奏同步?别用 opacity 闪
单独用 opacity 做光标会和打字脱节:打字停了光标还在闪,或者打完最后一字光标立刻消失。真正同步的做法是让光标也走 steps(),且帧数与打字一致。
做法是把光标定义为伪元素 ::after,宽度固定(如 2px),然后用同一组 @keyframes 控制它的 opacity:在每一步末尾设 opacity: 1,其余时间 opacity: 0。这样光标只在“当前字符显示完成”的瞬间亮起,视觉上就是打完一个字,光标才跳到下一个位置。
- 不要给光标加
transition,它必须硬切,否则模糊焦点 - 若文本含中文,
ch单位在部分字体中不等于中文字符宽度,此时应改用em(设font-size后测算)或退回到 JS 方案
ch 不是万能单位,字符数算错、字体未锁定、display 类型不对——这三个点占了 90% 的调试时间。


















