打字机动画需用块级或行内块容器,强制 white-space: nowrap 与 overflow: hidden 配合;光标必须用 border-right 实现;ch 单位在中文中不精准,推荐 JS 动态计算宽度。

HTML结构必须用块级容器包裹文本,不能直接套在内联元素上
直接给 <span></span> 或 <a></a> 加打字机动画会失效——因为 width 动画对默认的 inline 元素不生效。浏览器会忽略 width 变化,导致动画卡在 0 宽度或直接跳到满宽。
必须显式设为块级或行内块:display: block 或 display: inline-block。常见错误是只写 overflow: hidden 和 white-space: nowrap,却漏掉 display 声明。
- 推荐用
<p class="typewriter">文本</p>或<div class="typewriter">文本</div> - 若需保持行内流式布局(比如嵌在段落中),用
inline-block并加vertical-align: bottom避免基线错位 - 绝对不要把
class="typewriter"直接加在<h1></h1>上却不重置其默认 margin/padding——会导致动画宽度基准偏移
CSS里white-space: nowrap不是可选项,是硬性前提
一旦文本含空格或中文全角字符,white-space: normal(默认值)会让换行提前触发,width 动画还没走完,文字就折行了。结果是:前半截“打”出来,后半截突然掉到下一行,光标还卡在第一行末尾。
这个属性必须和 overflow: hidden 成对出现,否则换行 + 溢出 = 文本错乱显示。
立即学习“前端免费学习笔记(深入)”;
- 中英文混排时尤其敏感,比如 “Hello 世界” 中的空格会被当换行点
- 如果文案本身需要保留换行(如多行诗句),CSS 方案彻底不适用,必须切 JS 分行控制
- 某些字体(如部分思源黑体变体)对全角空格渲染异常,可临时用
替代普通空格保节奏
光标必须用border-right,别碰::after伪元素
用 ::after 画光标看似灵活,实际在 Safari 和旧版 Chrome 中常出现两个问题:动画不同步(光标闪得比打字快/慢)、伪元素脱离 width 动画影响范围,导致光标停在错误位置。
border-right 是唯一能和 width 动画同频响应的方案,因为它本身就是容器盒模型的一部分。
- 务必加
box-sizing: border-box,否则 border 宽度会额外增加容器总宽,让 steps() 步进错位 - 闪烁动画里不要改
border-width(触发布局重排),只改border-color或opacity - 移动端 iOS Safari 对
border-right的抗锯齿处理较弱,建议设最小 1px,避免 0.5px 模糊
ch单位要慎用,中文场景优先测真实宽度
20ch 理论上≈20个“0”字宽,但中文字体里“一”“龘”“0”宽度差异大。实测发现:Noto Sans CJK 中,“一”比“0”窄约 8%,32ch 动画结束时,最后两字可能被截断。
这不是 bug,是字体度量事实。强行用 ch 容易在设计稿和上线后出现肉眼可见的“少打两个字”问题。
- 最稳做法:用 JS 读取目标元素
offsetWidth后动态设动画终点,适合 SSR 渲染后 hydrate 场景 - 次选:用
max-width: fit-content+width: 0起手,靠动画覆盖自然宽度,兼容多数中文字体 - 纯静态页且文案固定,手动数字符+微调时间更省事,比如 18 字中文设
width: 18.5ch+animation-duration: 1.6s



















