ch单位在打字动画中表示“0”字符宽度,等宽字体下与字符宽度一一对应,需配合steps(n,end)逐字符显示、overflow:hidden防溢出及font-family:monospace确保精度。

ch单位在打字动画里到底怎么用?
ch 是 CSS 中一个常被低估的相对单位,它等于当前字体中 “0” 字符的宽度(不是所有字体都一样)。对等宽字体(如 monospace、Consolas、Fira Code)来说,ch 和字符宽度几乎一一对应——这正是打字效果能“卡准位置”的关键。
- 动画目标是让
width从0ch逐步增长到文本总长度(比如24ch),而非用px或em硬估 - 必须确保父容器使用等宽字体,否则
ch会失准;可显式设置font-family: monospace - 不要用
content伪元素配合ch做宽度控制——伪元素无法继承ch的上下文宽度计算逻辑
steps() 动画为什么必须用 steps(1, end)?
打字效果的本质是“逐字符出现”,不能平滑过渡。CSS 的 steps() 函数就是为此设计的,但参数选错就全乱了:
-
steps(1, end)表示:整个动画只分 1 步,且该步在时间结束时生效 → 实际表现为“突然显示全部”,显然不对 - 正确写法是
steps(N, end),其中N必须等于文本字符数(含空格),例如 12 个字符就写steps(12, end) -
end表示每步在区间末尾跳变,符合“光标停稳后才打出下一个字符”的直觉;用start会导致首字符初始即显示 - 若字符数动态变化(如 JS 插入内容),不能硬编码
steps()数值,需用 JS 计算后注入style或 CSS 变量
完整实现要绕开哪些坑?
打字动画看似简单,实际部署时高频出问题:
- 容器必须设
overflow: hidden,否则超长文字会撑开容器或溢出显示 - 动画属性只能作用于
width,不能用clip-path或mask混用——后者不支持ch单位,且steps()对clip-path支持极差(Safari 直接失效) - 不要给文字加
white-space: nowrap后再设固定宽——这会让ch失去意义,且换行逻辑被破坏 - 动画时长建议按字符数线性计算,比如
12ch文本配1.2s,即0.1s/ch;太快看不清,太慢像卡顿
code {
display: inline-block;
width: 0ch;
white-space: pre;
font-family: monospace;
overflow: hidden;
animation: typing 2.4s steps(24, end), blink 0.8s step-end infinite;
}
@keyframes typing {
to { width: 24ch; }
}
@keyframes blink {
50% { border-right-color: transparent; }
}
响应式下 ch 还可靠吗?
ch 本身是响应式的——字号缩放时,1ch 自动等比缩放。但问题出在「字符数」和「视觉节奏」上:
- 移动端字号变小,相同字符数下
ch总宽变窄,若动画时长不变,会显得过快 - 更稳妥的做法是把动画时长绑定到
font-size:用calc(0.1s * (1rem / 16px))类似逻辑(需配合 CSS 变量 + JS 计算) - 如果文本可能换行(比如响应式断点触发
white-space: normal),ch宽度控制就彻底失效——此时应改用 JS 驱动的字符级span插入,而非纯 CSS 方案
真正难的不是写出第一版动画,而是让 ch 值、steps() 数、字体栈、断点逻辑四者始终对齐。稍有脱节,光标就卡在半路,或者最后几个字直接闪现。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











