打字动画 CSS

2,531 阅读2分钟

前言

有时候我们希望一段文字可以逐字符显现,模拟出打字的效果。我们尝试用 CSS 来说实现这种效果。

第一步

需要展示的文本:

<h1>hello world!</h1>

添加动画,文字宽度从 0 变到最大:

@keyframes typing {
  from {
    width: 0;
  }
}

h1 {
  width: 180px;
  overflow: hidden; // 隐藏超出的部分
  white-space: nowrap; // 文本不换行
  animation: typing 8s;
}

我们发现这效果是不符合我们的需求的,问题有:

  1. 这个动画是连贯的,不是逐字出现的。
  2. 我们目前指定了一个宽度 180px, 这个是写死的,不同长度的文本,我们应该怎么去计算?

第二步

  • 针对第一个问题,我们可以用 steps() 进行处理。
  • 针对第二个问题,我们可以用 ch 这个css单位进行缓解。

ch 它表示的是 “0” 字形的宽度,而在等宽字体中,“0” 字形的宽度和其他所有字形的宽度是一样的,因此问题可以用 ch 单位来表达文字的宽度。

修改以后的css为

h1 {
 font: bold 200% Consolas, Monaco, monospace; // 等宽字体
 width: 12ch; // 文本宽度
 overflow: hidden;
 white-space: nowrap;
 border-right: 2px solid;
 animation: typing 8s steps(12); // 包含空格和符号,一共12个字符
}

第三步

我们发现还少了光标,我们使用 border-right 模拟光标:

// 光标动画
@keyframes caret {
 from {
   border-color: transparent;
 }
}

h1 {
 font: bold 200% Consolas, Monaco, monospace;
 width: 12ch;
 overflow: hidden;
 white-space: nowrap;
 border-right: 2px solid; // 右边框模拟光标
 animation: typing 8s steps(12), 
            caret 1s steps(2) infinite; // 动画
}

完整css示例

@keyframes typing {
  from {
    width: 0;
  }
}

@keyframes caret {
  from {
    border-color: transparent;
  }
}

h1 {
  font: bold 200% Consolas, Monaco, monospace;
  width: 12ch;
  overflow: hidden;
  white-space: nowrap;
  border-right: 2px solid;
  animation: typing 8s steps(12), 
             caret 1s steps(2) infinite;
}

参考