Typewriter Effect with CSS

How to create a simple typewriter effect using pseudo-elements and animations.

A reddit user asked in the CSS channel if there was a way of building a typewriter effect. Some people pointed out at Geoff Graham’s article on CSS Tricks (which includes different versions in CSS and JS), and many more recommended using JavaScript or some JS libraries/modules… and I tried to come up with my own CSS-only version:

Pros and Cons

Pros of this approach:

  • It doesn’t cut letters/words: each letter is added individually instead of hiding with overflows that may display them partially (as it happens in other solutions).
  • No need for monospace fonts: related to the point above. Other animations only work with monospace to go around the cutting words/letters issue. This one will work with non-monospace fonts too.
  • It involves a lot of code: the CSS animation will have as many lines as letters are in total… which is annoying, but in some cases, it may still be less code and less weight than with a JS solution.
  • It is a pain to write the animation steps: a lot of calculations! So I created a small script to generalize the process.

Accessibility

We are going to do a couple of things to boost the accessibility of this animation… and one of them consists of removing the animations 😅

<h1 aria-label="I'm a developer, writer, reader, and human.">
I'm a&nbsp; <span class="typewriter"></span>
</h1>
@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;
}
}

Full-Stack Software Engineer, Mobile Developer, Web technologies enthusiast. CSS aficionado. Twitter: @alvaro_montoro

Full-Stack Software Engineer, Mobile Developer, Web technologies enthusiast. CSS aficionado. Twitter: @alvaro_montoro