用steps()实现打字机效果的关键是离散步进:width或max-width动画配合steps(n,end)将显示过程切成n步,每步末尾瞬间显现一个字符;必须设white-space:nowrap和overflow:hidden,且需animation-fill-mode:forwards保证动画后内容可读。

直接用 steps() 配合 width 或 max-width 动画就能实现,不需要 JavaScript,但必须设 white-space: nowrap 和 overflow: hidden,否则动画会失效。
为什么用 steps() 而不是 ease 或 linear
打字机效果本质是“离散步进”——每个字符出现是瞬间的,不是平滑过渡。用 ease 会看到文字拉伸变形;linear 会让宽度匀速增长,视觉上仍是“滑入”,不是“逐字弹出”。steps(n, end) 把整个动画切成 n 段,每段结束才跳到下一个状态,刚好模拟敲击节奏。
-
steps(20, end)表示 20 步,第 1 步显示第 1 个字符,第 2 步显示前 2 个……第 20 步显示全部 -
n值要接近文本字符数(含空格),太小会漏字,太大导致末尾卡顿 - 别用
steps(1)或steps(2)——那只是“闪现”,不是打字
width vs max-width:选哪个更稳
两者都能用,但行为有关键差异:width 要求父容器有明确宽度(比如 display: inline-block 或固定 width),否则可能撑不开;max-width 更鲁棒,它只限制最大可见宽度,不干扰布局流,尤其适合响应式场景。
- 用
width时,必须确保元素有display: inline-block或块级上下文,否则动画无效 - 用
max-width可直接作用于inline元素(如<span></span>),无需额外包裹或 display 调整 - 若文本含中文、Emoji 或全角符号,
max-width: 100%比width: 100%更少受字体度量影响
光标(caret)怎么加才不干扰动画
光标本质是伪元素 + 独立闪烁动画,必须和打字动画解耦,否则容易错位或卡死。
立即学习“前端免费学习笔记(深入)”;
- 用
::after生成光标,position: absolute定位在文本末尾右侧 - 光标动画用单独的
@keyframes blink-caret,animation: blink-caret 0.75s step-end infinite - 别把光标塞进主动画里——比如写成
animation: typing 3s, blink-caret 0.75s是可以的,但两个动画 duration 和 timing 必须独立控制 - 如果光标跳动不同步,检查是否忘了
white-space: nowrap——换行会导致::after错位
最易被忽略的一点:动画完成后,元素仍需保持可读性与可访问性。animation-fill-mode: forwards 必须显式设置,否则动画一停就回退到 width: 0,屏幕阅读器可能读不到内容;同时避免用 visibility: hidden 或 opacity: 0 做初始隐藏——它们会让辅助技术跳过该文本。


















