打字动画
难题
有些时候,我们希望一段文本中的字符逐个显现,模拟出一种打字的效果。这个效果在技术类网站中尤为流行,用等宽字体可以营造出一种终端命令行的感觉。如果使用得当,它确实可以让整个网页的设计感提升一个档次。
解决方案
核心思路就是:让容器的宽度称为动画的主体,把所有文字包裹在这个容器中,然后让它的宽度从 0 开始以步进动画的方式一个字一个字地扩张到它应有的宽度。但是,这个方法是有局限性的,它并不适应于多行文本。然而幸运的是,这种情况通常需要应用在类似标题的但行文本上。另外,要注意:动画的持续时间越长,动画效果越差。
把动画应用在 h1 上,代码结构为:
<h1>这是一个要实现打字动画的标题</h1>
添加动画,让它的宽度从 0 变化到完整的宽度。
@keyframes typing {
from {
width: 0 }
}
h1 {
width: 14em;
animation: typing 8s;
}
然而,我们看到了这个效果跟想要的打字效果一点关系都没有。首先,忘记用 white-space:nowrap; 来阻止文本折行,因此文本的行数会随着宽度的扩张不断变化。其实没有加 overflow:hidden; 所以超出宽度的文本没有被裁切掉。修改了这两个问题后,效果如下:
![7f0d46751ecf5e4689559afffbb90995.gif](https://i-blog.csdnimg.cn/blog_migrate/f1df8a829161f5fabb87609cfbb2825b.gif)
修复了上述两个小问题后,发现真正的大问题才出来:
- 最明显的是整个动画是平滑连贯的,而不是逐字显现的。
- 另外,h1 的宽度怎么计算。
用 steps() 来修复第一个问题,就像“逐帧动画”和“闪烁效果”中的那样,所需要的步进数量是由字符的数量来决定的,这显然是很难维护的,而且对于动态文字来说更难。h1 的宽度取做字符数,因为用的是汉字,因此单位是 em
根据上述的修改一下:
@keyframes typing {
from {
width: 0; }
}
h1 {
width: 14em; /* 文本的宽度 */
overflow: hidden;
white-space: nowrap;
animation: typing 6s steps(15);
}