前言
背景知识:
基本的CSS动画
,逐帧动画
,闪烁效果
有些时候,我们希望一段文本中的字符逐个显现,模拟出一种打字的效果。这个效果在技术类网站中尤为流行,用等宽字体可以营造出一种终端命令行的感觉。如果使用得当,它确实可以让整个网页的设计感提升一个档次。
这篇文章我们就用CSS来实现一下这个效果~✨
解决方案
核心思路就是让容器的宽度成为动画的主体:
把所有文本包裹在这个容器中,然后让它的宽度从0开始以步进动画的方式、一个字一个字地扩张到它应有的宽度。
你可能已经察觉到了,这个方法是有局限的:它并不适用于多行文本。
好的,我们开始写代码吧!假设我们需要把这个动画效果应用到h1标题上,并且已经它把设置为等宽字体了,结构代码如下所示
<h1>CSS is awesome!</h1> 复制代码
🧑1.0版本
我们很容易地给他加上动画,让他宽度从0变化完整的宽度
/* *1.0版本 */ @keyframes typing { 0% { width: 0 } } h1 { background: lightgreen; font: bold 200% Consolas, Monaco, monospace; width: 8.25em; animation: typing 8s ; } 复制代码
我们可以看到产生的效果简直就是车祸现场😱,跟我们想要的的打字效果没有一点关系。
👦1.1版本
宝儿你可能已经猜到问题出在哪儿了,我们忘了用white-space:nowrap;
来阻止文本折行,因此文本的行数会随着宽度的扩张不断变化。其次,我们忘了加上overflow: hidden;
,所以超出宽度的文本没有被裁切掉。我们完善一下代码
/* *1.1版本 */ @keyframes typing { 0% { width: 0 } } h1 { background: lightgreen; font: bold 200% Consolas, Monaco, monospace; width: 8.25em; white-space: nowrap; overflow: hidden; animation: typing 8s steps(15); } 复制代码
值得注意的是我们这里的逐帧动画是通过设置steps实现的,我们所需要的步进数量是由字符的数量来决定的,这显然是很难维护的,而且对于动态文字来说更是不可能维护的。不过,我们稍后将看到,可以用一小段JavaScript代码来把这件事情自动化。
🕵️♂️2.0版本
/* *2.0版本 */ @keyframes typing { 0% { width: 0 } } @keyframes caret { 50% { border-right-color: transparent; } } h1 { /*background: lightgreen;*/ font: bold 200% Consolas, Monaco, monospace; /* width: 8.25em; */ width: 15ch; white-space: nowrap; overflow: hidden; border-right: .05em solid; animation: typing 8s steps(15), caret 1s steps(1) infinite; } 复制代码
2.0版本我们我们使用了ch
单位,这个ch单位是由CSS值与单位(第三版规范引入的一个新单位,表示“0”字形的宽度。它应该是最不为人知的一个新单位,因为在绝大多数场景下,我们并不关心0这个字符显示出来到底有多宽。但对等宽字体来说,这是个例外。在等宽字体中,“0”字形的宽度和其他所有字形的宽度是一样的。因此,如果我们用ch单位来表达这个标题的宽度,那取值实际上就是字符的数量,在本例子中,也就是15。
同时我们添加了闪烁光标,我们用右边框来模拟光标效果,同时给光标设置闪烁的动画,将光标设置为透明即可,要注意的,光标的动画是无限循环的!
这个动画现在的表现相当完美了,不过还不是很易于维护:需要根据每个标题的字数来给它们分别指定不同的宽度样式,而且还需要在每次改变标题内容时同步更新这些宽度样式。显然,这种场景正是JavaScript的用武之地:
🕵️♀️2.1终极版本
/* *2.1终极版本 */ @keyframes typing { 0% { width: 0 } } @keyframes caret { 50% { border-right-color: transparent; } } h1 { font: bold 200% Consolas, Monaco, monospace; white-space: nowrap; overflow: hidden; border-right: .05em solid; animation: typing 8s, caret 1s steps(1) infinite; } 复制代码
const doc = document.querySelector('h1') let len = doc.textContent.length, s = doc.style s.width = len + 'ch' s.animationTimingFunction = 'steps('+len+')' 复制代码
只需短短几行JavaScript代码,我们避免了手动计算字符数量和步进数量,取得两全其美的结果:不仅动画生动逼真,而且代码易于维护!
试一试
参考资料:《CSS揭秘》
最后
⚽本文带领大家实现了打字的动画效果,相信阅读完你一定有了不小的收获~
⚾如果你对这篇文章感兴趣欢迎点赞关注+收藏,更多精彩知识正在等你!😘