打字机效果需用@keyframes动画width至具体值(如12ch),禁用auto/fit-content;光标用border-right闪烁,避免::after;混排文本宜按字符数设时长或steps();ch单位不兼容旧版safari需@supports降级为em。

用 @keyframes 控制宽度实现打字机效果
核心是让容器宽度从 0 逐步展开到文本实际宽度,配合 overflow: hidden 截断溢出内容。不能直接动画 width: auto,必须用固定值或 ch 单位预估,否则动画无效。
-
width动画必须是可计算的具体值(如12ch、80px),不能是fit-content或max-content - 推荐用
ch单位(1ch ≈ 当前字体下 “0” 的宽度),比像素更适配字体缩放和等宽/非等宽字体 - 如果文本长度不确定,需 JS 测量
offsetWidth后动态设style.width,纯 CSS 无法自适应变长文本
光标闪烁必须用 border-right 或 box-shadow
用 ::after 伪元素加 content: "|" 看似简单,但会触发重排,且在中文字体下光标位置常偏移。更稳的方式是给文本容器加一个右侧边框模拟光标,并单独控制其闪烁动画。
- 光标用
border-right: 2px solid currentColor,颜色随文本自动继承 - 闪烁靠
animation: cursor 1s step-end infinite,step-end避免淡入淡出,保持硬切换感 - 不要用
opacity动画光标——Safari 旧版本对opacity在border上的支持不一致
动画时长与字符数不匹配导致“卡顿”
如果所有字符统一用一个 width 动画,等宽字体下尚可,但遇到中文+英文混排(如 “Hello世界”),每个字符视觉宽度差异大,12ch 可能撑太满或不够,造成最后一截突然弹出。
- 安全做法:按字符数设动画时长,例如 10 个字符 →
animation-duration: 5s(即 0.5s/字符) - 避免用
ease缓动函数,改用steps(10, end)模拟逐字出现(需配合width分段或 JS 插入 span) - 纯 CSS 下最简方案:接受轻微误差,用
ch估算总宽 +linear动画,对大多数标题已足够自然
IE 和 Safari 15.4 之前不支持 ch 单位动画
在这些浏览器里,width: 10ch 会被忽略,退成 width: auto,导致动画失效或光标错位。不是所有用户都用新浏览器,得有降级路径。
立即学习“前端免费学习笔记(深入)”;
- 加一层
@supports (width: 1ch)媒体查询,只在支持的环境启用ch方案 - 降级用
em(1em ≈ 字号大小),虽不精确但至少能动起来;中文场景下1.2em/ 字较稳妥 - Safari 15.4 以下需额外加
-webkit-animation前缀,且避免在@keyframes中使用 calc() 表达式
真正麻烦的是响应式场景:窗口缩放后字体大小变化,ch 值跟着变,但动画已启动,宽度就对不上了。这时候要么监听 resize 重设动画,要么放弃纯 CSS,交给 JS 控制节奏。










