使用 CSS 实现打字机效果

2025-05-25

使用 CSS 实现打字机效果

一位Reddit 用户在 CSS 频道询问是否有办法实现打字机效果。一些人推荐Geoff Graham 的《CSS Tricks》文章(其中包含 CSS 和 JS 的不同版本),还有更多人建议使用 JavaScript 或一些 JS 库/模块……而我则尝试自己实现一个纯 CSS 版本

这个想法是让content伪元素的属性动起来,比如::before一次显示一个字符。然后,我们可以使用该::after元素来显示闪烁的插入符号。

content属性是可离散动画的。这意味着不会有过渡效果(如果能实现就更好了),但它仍然会“逐步”地进行动画处理,这正是我们想要的。

它并非完美,但足够吸引眼球,而且与类似的纯 CSS 解决方案相比,它有一些不错的优势。此外,它还具有一些可定制性(插入符号可以更改颜色和大小),我尽力让它尽可能易于使用。

主要问题在于计算步骤以及它们必须发生的时间。为了简化和概括这个过程,我创建了一个简短的 JavaScript 代码片段,用于生成任意单词集的动画步骤……可惜的是,虽然它在大多数情况下都能正常工作,但我的计算有误,有时会失败。(一旦确认它正常工作,我会添加链接。)

优点和缺点

这种方法的优点:

  • 它是多行的:许多纯 CSS 打字机动画仅适用于单行/单字。这个动画也可以用于多行。
  • 它不会剪切字母/单词:每个字母都是单独添加的,而不是通过溢出来隐藏,从而可能部分显示它们(就像在其他解决方案中发生的那样)。
  • 无需等宽字体:与上一点相关。其他动画只适用于等宽字体,以避免剪切单词/字母的问题。这个动画也适用于非等宽字体。

这种方法的缺点:

  • 需要一些可访问性提升(见下文):在我看来,大多数执行此操作的动画(CSS 或 JS)都有这个问题。
  • 这涉及到大量的代码:CSS动画的行数和字母总数一样多……而且编写起来非常痛苦:需要进行大量的计算!所以我创建了一个小脚本来简化这个过程。
  • 并非所有浏览器都支持:某些浏览器不支持伪元素的动画(最明显的是 Mac 和 iOS 上的 Safari)。

为了解决最后一部分,或许我可以使用steps()计时功能。但最终,它也需要一些(更简单的)计算。

无障碍设施

我们将采取一些措施来提高此动画的可访问性...其中之一就是删除动画😅

首先,虽然视力正常的用户可以看到文本的变化,但辅助技术 (AT) 用户可能看不到。例如,屏幕阅读器用户无法获得文本变大/缩小的信息——这很麻烦,因为那会很麻烦!

为了避免获得标题的一半描述,我们应该aria-label向容器中添加具有完整描述的描述。

<h1 aria-label="I'm a developer, writer, reader, and human.">
  I'm a&nbsp; <span class="typewriter"></span>
</h1>
Enter fullscreen mode Exit fullscreen mode

如果没有aria-label,屏幕阅读器会将标题读为“我是”;有了aria-label,它们会读为“我是开发人员、作家、读者和人类。 ”,这样要好得多。

为了让组件更容易访问,我们可以做的另一件事是移除实际的动画。如果用户启用了“减少动画”设置,我们应该停止插入符号的闪烁,使其保持固定,并可能显示完整的单词,而不是逐个字母地显示。为此,CSS 使用了prefers-reduce-motion媒体查询:

@media (prefers-reduced-motion) {
  /* let the caret be fixed instead of blinking */
  .typewriter::after {
    animation: none;
  }

  /* replace the letter popup for a shorter animation */
  @keyframes sequencePopup {
    0%, 100% { content: "developer"; }
    25% { content: "writer"; }
    50% { content: "reader"; }
    75% { content: "human"; }
  }

  .sequencePopup::before {
    content: "developer";
    animation: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

我们并没有完全移除动画;只是用一个更易于访问的动画替换了它。并非所有动画都是不好的,“减少动效”并不意味着“没有动效”。

文章来源:https://dev.to/alvaromontoro/typewriter-effect-with-css-38im
PREV
如何:使用 JavaScript 构建一个简单的搜索栏
NEXT
如何使用 HTML 和 CSS 创建进度条(视频)