纯 css 打字机动画最轻量且兼容性好,但仅适用于静态文本;其核心是用 steps(字符数, end) 配合 width 动画与 overflow: hidden 逐字显示,需严格匹配字符数、设置 white-space: nowrap 并用 border-right 实现光标闪烁。

纯 CSS 实现的打字机动画最轻量、兼容性好,但只适用于静态文本;JS 方案支持循环、多行、暂停/重置等交互,适合真实项目。
纯 CSS 打字机:用 steps() 控制逐字显示
核心是把文字“藏”在容器里,再靠 width 动画 + steps(字符数, end) 模拟逐字打出。关键点不是“动画时间”,而是 steps() 的步数必须和实际字符数严格一致(包括空格和标点),否则会跳字或卡顿。
-
white-space: nowrap必须加,否则换行会破坏宽度计算 -
overflow: hidden要设在父容器上,不能只设在文本元素上 - 光标用
border-right+animation: blink-caret .75s step-end infinite,step-end避免闪烁过渡 - 若文本含中文或全角符号,需手动数清字符数——浏览器不会自动按“字”切分,
steps(20)对 20 个 ASCII 字符有效,对 10 个中文可能就过快
JavaScript 打字机:用 setTimeout 或 requestAnimationFrame
JS 方案真正可控:能读取数组轮播、响应用户点击、中途插入停顿、适配屏幕宽自动换行。但要注意递归调用时的闭包陷阱和内存泄漏。
- 别直接用
for循环 +setTimeout,i 值会全部变成最终值;改用立即执行函数或let声明 - 每轮打字后,应检查目标元素是否还存在于 DOM 中(比如页面切换后),避免
Cannot set property 'textContent' of null - 想实现“打一半暂停”,不要清空定时器再重开,而是在每次
setTimeout前判断一个isPaused标志位 - 用
requestAnimationFrame替代setTimeout更流畅,但需自行计算帧间隔,对初学者反而更难调速
常见错误:animationend 事件不触发
CSS 动画结束后想执行后续逻辑(比如显示按钮),但 animationend 经常监听不到。根本原因是:动画没真正“播放”,比如元素初始 display: none 或 opacity: 0 且未触发重排。
- 确保元素已渲染:可在
setTimeout(() => { el.style.animation = '...' }, 0)强制触发重排 - 监听事件要带浏览器前缀:
el.addEventListener('animationend', handler)、el.addEventListener('webkitAnimationEnd', handler) - 如果用了
forwards填充模式,动画结束后样式已定格,此时再改animation属性不会重新触发animationend
真正麻烦的从来不是写出第一版效果,而是当设计要求“首字延迟 0.5s、中间逗号停顿 300ms、最后一句渐显”时,CSS 方案基本崩盘,JS 逻辑迅速变得难以维护——这时候该考虑抽离成类,而不是硬塞条件判断。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











