可扩展的 CSS 打字机效果
您希望文本具有打字机效果,但却迷失在使用 JS 和使用复杂 CSS 代码的所有变体中。
不用再搜索了!这是一个简单的打字机效果,只需几行 CSS,无需任何复杂的代码。它可扩展,适用于任何类型的文本。
观看实际效果:
它是如何工作的?
逻辑非常简单,依赖于基本的 HTML 代码:
<span class="type"><span>CSS typewriter</span></span>
只需将文本放在两个元素之间<span>
即可。无需处理伪元素、重复文本、数据属性等问题。
现在的 CSS:
.type {
display:inline-flex;
}
.type span {
word-break: break-all;
height: 1.2em;
width:0%;
overflow: hidden;
animation:t 2s linear infinite alternate;
}
.type span:before {
content:" ";
display:inline-block;
}
@keyframes t{
90%,100% {width:100%}
}
没事,我什么都没忘。这就是打字机效果所需的全部 CSS。
为了达到最终结果,我们使用了 3 个技巧:
1)循环百分比大小
这是一个强大的 CSS 怪癖,用于计算元素的宽度(或高度)。我使用了第一个<span>
having display:inline-flex
,因此它的大小取决于其内容(它是一个内联元素)。其内部的内容(另一个<span>
)使用百分比宽度,因此宽度基于其容器。由于每个元素都依赖于其他元素,因此我们有一个循环计算!
规范详细说明了此类行为。我不建议阅读它,因为你可能会感到困惑(我读了十遍才理解几个案例)。
我会尝试用简单的语言来解释我们所遇到的情况。
- 首先,浏览器会忽略百分比宽度来定义容器的宽度。子元素的宽度将为
width:auto
。我们的第一个 span 的宽度将等于其子元素的宽度(也就是文本的宽度)。 - 然后浏览器将根据之前找到的父级宽度来计算子级的宽度,但父级的宽度不会再次改变,以免陷入无限循环。
换句话说,width:X%
我应用于 span 的动画是基于其自身内容的,因此我们不需要任何复杂的计算。我们只需要对元素进行从0%
到 的动画处理即可。100%
这是我们得到的:
2)打破言语
现在让我们添加word-break: break-all;
前面的代码:
我们越来越接近了。我们的文本正在逐个字母地循环。
break-all
在“单词”引用中允许断开
3)将高度固定为一行
最后一个技巧是将元素的高度设置为一行。默认情况下,一行的高度大约是,1.2xfont-size
这就是我使用的原因1.2em
。您必须根据您的情况或基于的值来调整此值line-height
(它应该等于line-height
)。
就是这样!我们有了打字机效果。
等一下,第一个字母有问题!
是的,很好。这就是为什么我在初始代码中添加了以下内容:
.type span:before {
content:" ";
display:inline-block;
}
这将创建一个不可见的首字母,以代替真实的首字母。
✔️ 无需 JavaScript
✔️ 简单的 HTML 代码
✔️ 无需复杂的 CSS 代码。声明少于 10 条,且无硬编码值
✔️ 易于访问。文本直接写在 HTML 代码中(无伪元素,无重复文本)
✔️ 您可以使用任何文本,无需更改代码。✔️
无需等宽字体
✔️ 无浏览器支持问题。我使用的所有属性均受大多数浏览器支持。我们还可以移除 flexbox:https://codepen.io/t_afif/pen/VwWvmxe
❌ 不支持多行文本。好吧,我需要一个缺点 😜
那么插入符号呢?
您可以使用 box-shadow 轻松添加一个:
那么多篇文本怎么样?
以上只是我所追求的“真实”打字机效果的第一部分。
观看实际效果:
HTML 代码仍然是基本的:
I am <span class="type">
<span>
<span>a CSS Hacker</span>
<span>an expert web developer</span>
<span>a lazy person!</span>
</span>
</span>
CSS:
.type {
display:inline-block;
}
.type > span {
display:grid;
overflow: hidden;
height:1.2em;
}
.type span span {
width:0%;
max-width:max-content;
overflow: hidden;
height:inherit;
word-break:break-all;
animation:
c 0.5s infinite steps(1),
t 2s linear infinite alternate,
m 12s steps(3) infinite;
}
.type span span:before {
content:" ";
display:inline-block;
}
@keyframes t{
90%,100% {width:100%}
}
@keyframes c{
0%,100%{box-shadow:5px 0 0 #0000}
50% {box-shadow:5px 0 0 red }
}
@keyframes m{
100% {transform:translateY(-300%)}
}
诀窍是让所有跨度彼此相邻(这就是我display:grid
在它们的父容器上使用它的原因),以便最长的单词将定义主元素的宽度。
然后,每个 span 都会像之前一样动画。唯一的区别是,我使用了一个小小的变换技巧,每次只显示一个 span。
overflow:hidden
如果从第二个跨度中删除,您可以看到发生了什么:
请注意使用max-width:max-content
限制插入符号为实际文本的宽度而不是主元素的宽度。
您还会注意到 3 与许多值一起使用:
- 12秒=3*(2*2秒)
- 步骤(3)
- 平移Y(-300%)=平移Y(3*-100%)
是的,该值可以是 CSS 变量。这样我们的代码将变得可扩展,我们可以轻松添加任意数量的文本:
我们有可扩展的 CSS 打字机效果:
✔️ 无需 Javascript
✔️ 基本 HTML 代码
✔️ 无需复杂的 CSS 代码
✔️ 可访问
✔️ 适用于任何文本内容
✔️ 可使用任何字体
✔️ 可扩展
✔️ 无浏览器支持问题
