css打字效果需用@keyframes控制width从0到实际宽度并配合overflow:hidden,容器须设固定宽(推荐ch单位),加white-space:nowrap和border-right模拟光标;逐行显示必须用js拆分换行符后动态插入文本节点。

用 CSS @keyframes 实现基础打字效果
核心思路是控制 width 从 0 到文本实际宽度,配合 overflow: hidden 截断溢出。必须给容器设固定宽度(或用 ch 单位匹配字符数),否则动画无效。
常见错误:直接对 div 应用动画却没设 white-space: nowrap,导致换行破坏逐字节奏;或忘了加 border-right 模拟光标,显得生硬。
-
width动画值建议用ch单位(如20ch),比百分比更准——1ch≈ 当前字体下一个 “0” 字符的宽度 - 光标闪烁用
border-right: 2px solid;+animation: blink 1s infinite,别用outline,它不随文字宽度收缩 - 动画时长按字符数微调:20 字建议
2s,太快像闪现,太慢用户会失去耐心
JavaScript 控制逐行显示(解决换行问题)
CSS 方案天然不支持“逐行”,只能整段打字。要实现真正的逐行(比如每行停顿、不同速度),必须用 JS 拆分 textContent 并动态插入。
关键点在于:不能直接操作 innerHTML 插入 <br>,那会破坏 DOM 结构;应该用 document.createTextNode() 或 textContent 累加,再用 <div> 包裹每行。<ul>
<li>用 <code>String.prototype.split("\n") 获取行数组,避免正则或 match() 引入空行干扰
setTimeout,延迟时间建议设为 500 + Math.random() * 300,模拟人工停顿,比固定值更自然while (el.firstChild) el.removeChild(el.firstChild),比 innerHTML = "" 更安全(保留事件监听器)兼容性与性能陷阱
@keyframes 在 IE10+ 支持良好,但 Safari 旧版本对 ch 单位渲染不准;JS 方案则需注意 requestAnimationFrame 替代 setTimeout 的必要性——仅当需要精确帧率同步时才用,普通打字动画反而增加复杂度。
- 移动端 iOS Safari 可能因字体加载延迟导致初始
ch宽度计算错误,保险做法是等document.fonts.ready后再启动动画 - 长文本(>100 行)直接用 JS 逐行 append 会卡顿,应改用
DocumentFragment批量插入 - 禁用 JavaScript 时,CSS 方案仍可降级显示完整文本;JS 方案必须提供
<noscript></noscript>fallback 内容
一行代码快速启用(含光标与换行)
如果只是临时调试或简单页面,直接复制这段带注释的代码最省事:
function typeLine(el, lines, delay = 600) {
let i = 0;
function next() {
if (i >= lines.length) return;
el.textContent = lines[i++];
el.style.width = '0';
el.style.width = el.scrollWidth + 'px'; // 触发重排,让 width 生效
}
next();
setInterval(next, delay);
}
// 调用:typeLine(document.getElementById('typewriter'), ['第一行', '第二行'], 800);
注意 el.scrollWidth 是关键——它动态读取真实宽度,比预估 ch 值更可靠,尤其在字体不一致或缩放场景下。但别在循环里反复读,这里只读一次,够用。











