Typewriter Animation with Pure CSS

Use-Cases of this Tutorial

  • You are looking to know how to achieve a typewriter animation effect with CSS.

This tutorial discusses the concepts behind achieving typewriter effect with CSS, with no Javascript involved.


Twinkle, twinkle, little star.

Using a Monospace Font

A monospace font contains letters and characters of equal width. This is different from conventional fonts in which characters are of different width.

To achieve a typewriter effect, it is important to use a monospace font. A monospace font, along with a valid animation-timing-function, will ensure that only a single character comes up in each step of the animation.

Some examples of monospace fonts are Courier, Consolas, Roboto Mono etc

CSS Properties Being Animated

In achieving a typewriter effect, basically the width CSS property is being animated from 0% to 100%.

The cursor at the end is basically a border on the right side. The blinking effect is achieved by infinitely animating the border-color property, from a solid color to transparent.

Performing Animation in a Fixed Number of steps

The main hero of this animation is the animation-timing-function property. To look like a realistic typing effect, we want the animation to push out a single character at a time. We don't want the animation as a smooth movement from one state to another, because then it won't look realistic. (You can try it yourself by editing the below codes).

Setting animation-timing-function as steps makes sure that the animation is performed in a series of steps. In short you can specify the number of "frames" in the animation.

In case of the text "Twinkle, twinkle, little star." - which contains 30 characters, the value becomes steps(30, end). The second parameter "end" specifies the movement to stay at the end till the duration of the step is over.

See How to Use steps() in CSS Animations for more.

Complete Codes

<div class="typewriter">
    <div class="typewriter-text">Twinkle, twinkle, little star.</div>
.typewriter {
    font-family: Courier, monospace;
	display: inline-block;

.typewriter-text {
    display: inline-block;
  	overflow: hidden;
  	letter-spacing: 2px;
 	animation: typing 5s steps(30, end), blink .75s step-end infinite;
    white-space: nowrap;
    font-size: 30px;
    font-weight: 700;
    border-right: 4px solid orange;
    box-sizing: border-box;

@keyframes typing {
    from { 
        width: 0% 
    to { 
        width: 100% 

@keyframes blink {
    from, to { 
        border-color: transparent 
    50% { 
        border-color: orange;