Styling a single cursor Typewriter tutorial

1. Introduction

We are going to style a Typewriter animation with a single cursor typewriter.

To get started with the tutorial open and fork this StackBlitz. By using the sandbox you do not have to worry to much about setting up an entire development environment.

2. Files overview

In the sandbox you will see a couple of files, but these are the ones we are interested in:

  1. index.html contains the HTML for the two typewriters. It includes "uiloos" via the UNPKG cdn.
  2. main.js it contains a preconfigured single cursor typewriter which is not working yet, and is unstyled.
  3. main.css a CSS file which is loaded in the index.html. We will style the singlecursor animation here.

3. A basic animation

In the "index.html" file you will see a div with the id typewriter-text, it is this element to which we want to hook up our animation.

To do this open the "main.js" file and change the subscriber function to:

function subscriber(typewriter) {
  typewriterEl.textContent = typewriter.text;
}

The subscriber function is given as the second argument to the typewriterFromSentences function. This makes it a "subscriber" to the "Typewriter".

A "subscriber" is informed of each TypewriterEvent. It receives the Typewriter as the first parameter.

What our "subscriber" does: for each event that occurs set the text of the typewriterEl to whatever the text of the typewriter is.

You should see a basic animation:

A simple unstyled animation looping over matrix quotes

Not much to look at but it is a start.

4. Styling the Typewriter

By now you must realize that the typewriter contains quotes from the film franchise: "the Matrix". So lets give it a more matrix like feel.

Open the file name named "main.css" and add the following:

#typewriter {
  padding-top: 75px;
  padding-left: 16px;
  height: 150px;
  margin-bottom: 16px;

  font-family: monospace;
  font-size: 26px;
  color: #15803d;
  background-color: rgb(0, 16, 0);
}

This gives the animation a blackish green background, which resembles the style of the film. It also makes the font monospaced, the font depends on the operating system. Of course you could set it to a specific font instead.

Now the animation appears like this:

A styled animation looping over matrix quotes

Now it feels closer to the style of the film.

5. Adding the cursor

The one thing still missing is a cursor, this is the defining feature of a typewriter animation.

When you have only have a single cursor all we need to do is add a HTML element at the end of the text which represents the cursor.

The technique we are using is making the "subscriber" add an HTML element at the end of the text using document.createElement. Alternatively you could also place the cursor inside of the "index.html" file. There is almost always more than one way to achieve the same results.

Open the main.js file and change the "subscriber" function to:

function subscriber(typewriter) {
  typewriterEl.textContent = typewriter.text;

  const cursorEl = document.createElement("span");
  cursorEl.id = "typewriter-cursor";
  typewriterEl.append(cursorEl);
}

This ensures that a span is added after the text, which has the CSS class typewriter-cursor.

To style said CSS class open the "main.css" file and add the following:

#typewriter-cursor {
  margin-left: 2px;
  border-right-width: 4px;
  border-right-style: solid;
  border-color: #15803d;
}

We should now have a cursor:

A styled animation looping over matrix quotes showing a cursor

6. Blinking the cursor

The animation feels incomplete, maybe it is hard to put your finger on it, but the animations feels unnatural. The reason for this is that the cursor does not blink like a normal cursor does.

Blinking in cursors works like this: when the user is typing the cursor is solid. When the user stops typing the cursor will start blinking, but only after a period of inactivity.

Luckily for us the logic for when a cursor is blinking or not, is incorporated into the Typewriter, so we do not need to worry about the specifics.

What we are going to do is add a "blinking" CSS class to the cursors span element, when the Typewriter tells us the cursor is blinking.

Open the main.js file and change the "subscriber" for the last time:

function subscriber(typewriter) {
  typewriterEl.textContent = typewriter.text;

  const cursorEl = document.createElement("span");
  cursorEl.id = "typewriter-cursor";
  if (typewriter.cursors[0].isBlinking) {
    cursorEl.classList.add("blinking");
  }
  typewriterEl.append(cursorEl);
}

The typewriter will always have 1 or more cursors. Which is why you can use cursors[0] without worrying about it being undefined

The CSS class is not set. Now to make the cursor actually blink, open the "main.css" file and add the following:

#typewriter-cursor.blinking {
  animation: blink 0.75s step-start infinite;
}

@keyframes blink {
  from,
  to {
    border-color: transparent;
  }
  50% {
    border-color: #15803d;
  }
}

This sets an infinitely running animation, which alternates the cursors background between transparent and green.

The step-start makes the transition quite abrupt between the two states. You could also set it to ease-in or linear to get different effects.

The final result shows a blinking cursor when a sentence is finished:

A styled animation looping over matrix quotes showing a blinking cursor

7. Further reading

  1. Read through the API of the Typewriter.
  2. Now that you have mastered a single cursor animation, perhaps you want to check out a tutorial for a multi cursor animation.
  3. When using vanilla JavaScript you must handle DOM manipulation yourself, contrast this with the examples that use a framework.

8. Full code

For reference here is the full code for this tutorial.

Usage with Frameworks
Learn how to use the Typewriter in combination with frameworks such as Angular and Vue.