CSS 实现打字机效果
多行文本可以通过 steps() + width + overflow + white-space 来实现。
# 一、基础版:单行打字效果
<div class="typewriter">
<p>你好,这是一个打字效果的演示。</p>
</div>
1
2
3
2
3
.typewriter {
width: fit-content; /* 让容器适应内容 */
font-family: 'Courier New', monospace; /* 等宽字体,便于精确控制 */
}
.typewriter p {
width: 0;
overflow: hidden;
white-space: nowrap;
border-right: 2px solid; /* 模拟光标 */
animation:
typing 4s steps(20, end) forwards, /* 20需替换为实际字符数 */
blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from { width: 0 }
to { width: 40ch } /* 使用ch单位(字符宽度)更精确 */
}
@keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: black; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 原理
核心是:
steps(n)
1
把动画拆成 n 步,就像一个个字符出现。
width: 40ch
1
ch = 字符宽度单位。
# 二、多行文本打字效果(推荐方案)
纯 CSS 多行需要 控制高度逐步展开。
# HTML
<div class="typing-multi">
Hello World
This is CSS typing effect
Support multiple lines
Pure CSS animation
</div>
1
2
3
4
5
6
2
3
4
5
6
# CSS
.typing-multi {
width: 30ch;
overflow: hidden;
border-right: 2px solid #000;
white-space: pre-wrap;
line-height: 1.6;
animation:
typing-multi 6s steps(120) forwards,
blink .8s infinite;
}
@keyframes typing-multi {
from {
width: 0;
}
to {
width: 30ch;
}
}
@keyframes blink {
50% {
border-color: transparent;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 三、真正多行逐行输出
如果你希望 一行一行输出。
# HTML
<div class="container">
<p class="line">Hello World</p>
<p class="line">This is CSS typing effect</p>
<p class="line">Support multiple lines</p>
<p class="line">Pure CSS animation</p>
</div>
1
2
3
4
5
6
2
3
4
5
6
# CSS
.line {
width: 0;
overflow: hidden;
white-space: nowrap;
border-right: 2px solid transparent;
}
.line:nth-child(1) {
animation: typing 2s steps(20) forwards, cursor 0.5s step-end 4 alternate;
}
.line:nth-child(2) {
animation: typing 2s steps(25) 2s forwards, cursor 0.5s step-end 4 alternate 2s;
}
.line:nth-child(3) {
animation: typing 2s steps(22) 4s forwards, cursor 0.5s step-end 4 alternate 4s;
}
.line:nth-child(4) {
animation: typing 2s steps(22) 6s forwards, cursor 0.5s step-end infinite alternate 6s;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes cursor {
from { border-right-color: black; }
to { border-right-color: transparent; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
效果:
Hello World
↓
This is CSS typing effect
↓
Support multiple lines
↓
Pure CSS animation
1
2
3
4
5
6
7
2
3
4
5
6
7
逐行打字。
# 四、企业级优化版本(推荐)
适合 React / Vue / AI Chat UI。
.typing {
display: inline-block;
overflow: hidden;
white-space: nowrap;
border-right: 2px solid;
width: 0;
animation: typing var(--time) steps(var(--steps)) forwards;
}
@keyframes typing {
to {
width: 100%;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
HTML
<div class="typing" style="--time:3s;--steps:30">
Hello this is typing effect
</div>
1
2
3
2
3
优势:
- 动态控制字符数
- 组件化
- 适合 AI Chat
# 五、AI Chat 场景的更真实方案
像 ChatGPT / Claude 一样的效果:
CSS + JS
<div id="app">
<div id="text"></div>
</div>
1
2
3
2
3
#text {
font-size: 18px;
line-height: 1.6;
/* border-right: 2px solid black; */
display: inline-block;
padding-right: 4px;
animation: blink 1s infinite;
white-space: pre-wrap;
}
#text::after {
content: "|";
margin-left: 2px;
animation: blink 1s infinite;
}
@keyframes blink {
50% {
border-color: transparent;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
JS 控制字符流:
function typing(el, text, speed = 40) {
let i = 0
let last = 0
function frame(time) {
if (time - last > speed) {
el.textContent += text[i]
i++
last = time
}
if (i < text.length) {
requestAnimationFrame(frame)
}
}
requestAnimationFrame(frame)
}
const el = document.getElementById("text")
typing(
el,
"Hello World!\nThis is a typing effect demo.\nSupport multiple lines.",
60
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 六、纯 CSS 的限制
纯 CSS 有几个限制:
| 限制 | 原因 |
|---|---|
| 不能根据字符数自动计算 steps | CSS 不知道文本长度 |
| 多行控制困难 | 需要手动 delay |
| 动态文本不行 | CSS 静态 |
所以 AI Chat 必须 JS 控制。
# 七、如何实现打字效果?
如果是静态文本可以用 CSS
steps()实现:
overflow:hiddenwidthsteps(n)如果是动态 AI 流式文本,需要 JS 控制字符流,或者直接使用 SSE/WebSocket 的 chunk 更新。
上次更新: 2026/03/07, 04:39:17