Skip to content

打字动画

解决方案

思路:让容器的宽度称为动画的主题:把所有文本包裹在这个容器中,然后让它的宽度从 0 开始以步进动画的方式,一个字一个字地扩张到它应有的宽度

只适用于单行文本,如果要多行文本实现,需要每一行都包裹一层容器,同时还要维护合适的动画延时,文本多的话,这个动画的得不偿失了

还有一些细节,要设置字体为等宽字体,宽度的单位应该是一个等宽字体的宽度,即使用 ch 为单位

html
<h1>hello world</h1>
css
@keyframes typing {
    from { width: 0; }
}

h1 {
    width: 11ch; /* 11个字 */
    overflow: hidden; /* 剪切的方式 */
    white-space: nowrap; /* 不换行 */
    font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace; /* 等宽字体 */
    animation: typing 4s steps(11); /* 11 个字,所以 11 步 */
}

还可以添加光标效果,用右边框模拟光标,并让其有闪烁效果

css
@keyframes typing {
    from { width: 0; }
}
@keyframes caret { /* 闪烁动画 */
    50% { border-color: transparent; }
}

h1 {
    width: 11ch;
    overflow: hidden;
    white-space: nowrap;
    font-family: SimSun,Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
    border-right: 2px solid; /* 颜色随着字体颜色变化 */
    animation: typing 4s steps(11), caret 1s steps(1) infinite; /* 光标动画应该是无限执行的 */
}

但还有不易于维护的问题,所以可以通过一段 js 控制

js
const h1 = document.querySelector('h1')
const len = h1.textContent.length
h1.style.width = `${len}ch`
h1.style.animationTimingFunction = `steps(${len}), steps(1)`