---
title: "How To Create A Typewriter Effect In Vue | CoderPad"
description: "The typewriter effect is an animation that gives the impression that text is being typed on the screen one letter at a time, which can be a great way to grab a user's attention. Learn how you can grab your user's attention by implementing the typewriter effect in your Vue applications in this article."
canonical: "https://coderpad.io/blog/development/how-to-create-a-typewriter-effect-in-vue/"
last_modified: "2026-04-15 16:21:03"
---
[Back to blog](https://coderpad.io/blog/)

# How To Create A Typewriter Effect In Vue

November 30, 2022 6 Minute Read

By Taminoturoko Briggs

[Development](https://coderpad.io/blog/development/)

Typewriter effect is an animation that gives the impression that text is being typed on the screen one letter at a time, which can be a great way to grab a user’s attention. The typewriter effect can be created by using either CSS or JavaScript. Depending on the effect we want to create we will need to choose one over the other.

When using only CSS, we don’t have access to the text used for the effect but with JavaScript, we do, which means JavaScript has more potential to create a more feature-rich typewriter effect. For example, JavaScript is the best option if we want to create a deleting-and-retyping effect like the one on [CoderPad’s registration page](https://app.coderpad.io/register):

In this tutorial, we will learn how to create a coding typewriter effect that includes syntax highlighting just like the one used on Codepen’s landing page.

## Setting up

For this article, we’ll be making use of the Vue environment on the [CoderPad sandbox](https://app.coderpad.io/sandbox). To create a new Vue sandbox, click on the Language tab on the sidebar and select Vue from the Frontend section.

For adding syntax highlighting to our typewriter effect we will be using [vue3-highlightjs](https://www.npmjs.com/package/vue3-highlightjs). In the sandbox shell, install the`vue3-highlightjs`library:

```
$ npm i vue3-highlightjs
```

>

💡 The CoderPad sandbox automatically starts your application and applies changes made during development without needing a manual refresh.

## Creating a typewriter effect with CSS

The typewriter effect in CSS is achieved by gradually revealing the text by increasing the width of its element from 0 to 100% using the CSS animation`steps()`function. Then you’ll add a blinking border that acts as a cursor that types out the text. Let’s learn how it’s done with a simple`console.log`example.

First, we need to define the text to be used for the typewriter effect.

```
<script setup></script>

<template>
  <code>
    <div>
      <p class="typingEffect">
        console.log('Hello world')
      </p>
    </div>
  </code>
</template>

<style scoped>
  code {
    background-color: #202129;
    border-radius: 4px;
    padding: 20px;
    height: 70px;
    color: white;
    display: flex;
    margin: 0 auto;
    align-items: center;
    width: 350px;
  }
</style>Code language: HTML, XML (xml)
```

Next, let’s add the typing animation.

```
.typingEffect {
    width: 0;
    overflow: hidden; /* Ensure the text is not visible until the typewriter effect*/
    border-right: 2px solid white; /* The cursor*/
    font-size: 16px;
    white-space: nowrap; /* Keeps the text on a single line */
    animation: typing 2s forwards;
  }

/* The typing animation */
@keyframes typing {
  from { width: 0 }
  to { width: 100% }
}Code language: CSS (css)
```

After adding the above styles, here is what it will look like:

The sentence console.log(‘Hello world’) is printed word by word.

We can see some typing animation going on but this obviously isn’t what a typewriter effect looks like – we want to reveal the text letter by letter. This is where the CSS`steps()`function comes in. With the`steps()`function we can specify the number of steps the animation should take before completion.

```
.typingEffect {
  //…
  animation: typing 2s steps(30) forwards;
}Code language: CSS (css)
```

Here is what we get:

The sentence console.log(‘Hello world’) is printed word by word with a brief pause after printing.

That’s more like it! If we still want to adjust the speed to make it slower or faster we can just tweak the animation delay and`steps()`function.

There is one more thing left to add to get a perfect typewriter effect, and that is the blinking cursor. This can easily be achieved by infinitely animating the background color of the border from transparent to its original color with the following animation.

```
@keyframes blink {
  0%, 45% {
    border-color: transparent;
  }
  50%, 100% {
    border-color: white;
  }
}Code language: CSS (css)
```

Next, modify the type`typingEffect`class to use the`blink`animation.

```
.typingEffect {
  //…
  animation: typing 2s steps(30) forwards, blink 1s infinite;
}Code language: CSS (css)
```

Now, using what we have learned, let’s create the “coding” typewriter effect like you’d see in an IDE. First, let’s define the text for the typewriter effect:

```
<script setup></script>

<template>
  <code>
    <div>
      <p class="typingEffect__line1">
        function helloWorld() {
      </p>
    </div>
    <div>
      <p class="typingEffect__line2">
        console.log('Hello world')
      </p>
    </div><br>
    <div>
      <p class="typingEffect__line3">}</p>
    </div>
  </code>
</template>

<style scoped>
  code {
    display: block;
    background-color: #202129;
    padding: 20px;
    color: white;
    overflow: hidden;
    margin: 0 auto;
    align-items: center;
    width: 350px;
    height: 130px;
  }

  code div {
    display: inline-block;
  }

  .typingEffect__line2 {
    padding-left: 24px;
    box-sizing: border-box;
  }
</style>Code language: HTML, XML (xml)
```

Above we are placing each line of code in a different paragraph element so that the typing animation can be done a line at a time and proper indentation can be added to the code. Here is the result:

A`helloWorld()`function that logs “Hello world” to when called.

Next, to add the typewriter effect where the code will be revealed line by line, we will be adding an animation delay to the second and third lines of code to prevent their animation from starting until the previous one is complete.

```
code p {
  width: 0;
  margin-right: 5px;
  overflow: hidden;
  border-right: 2px solid transparent;
  white-space: nowrap;
}

.typingEffect__line1 {
  animation: typing 2s steps(30) forwards, blink 1s 3;
}

.typingEffect__line2 {
  animation: typing 2.5s steps(35) 3s forwards, blink 1s 3s 3;
}

.typingEffect__line3 {
  animation: typing 0s 6s forwards, blink 1s 6s infinite;
}

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

@keyframes blink {
  0%, 45% {
    border-color: transparent;
  }
  50%, 100% {
    border-color: white;
  }
}Code language: CSS (css)
```

Here is the result:

The function`helloWorld()`function printed in an animated style.

Finally, to add syntax highlighting, we will first add`vue3-highlightjs`to our app by modifying the`main.ts`file to the following:

```
import { createApp } from 'vue'
import App from './App.vue'
import vue3Highlightjs from 'vue3-highlightjs'
import 'highlight.js/styles/dracula.css'

createApp(App).use(vue3Highlightjs).mount('#app')Code language: TypeScript (typescript)
```

Then, we specify where we want to add highlighting using the`v-highlightjs`directive and the language to be highlighted. To do this, modify the template tag in`App.vue`to the following:

```
<template>
  <div v-highlightjs>
    <code class="javascript">
      <div>
        <p class="typingEffect__line1">
          function helloWorld() {
        </p>
      </div>
      <div>
        <p class="typingEffect__line2">
          console.log('Hello world')
        </p>
      </div><br>
      <div>
        <p class="typingEffect__line3">}</p>
      </div>
    </code>
  </div>
</template>Code language: HTML, XML (xml)
```

With this, we are done building our coding typewriter effect using only CSS.

## Creating the typewriter effect in Vue

The typewriter effect with Vue is achieved by appending one character at a time to a string which is then displayed in the interface. Then we simply add a blinking pipe character ( | ) or border that acts as a cursor that types out the text. Let’s learn how it’s done with a simple console.log example.

First, let’s create the typing area and define the text to be used for the typewriter effect:

```
<script setup>
import { ref } from 'vue';
const code = "console.log('Hello world')"
const typeValue = ref('')

</script>

<template>
  <code>
    <div>
      <p class="typingEffect">
        {{ typeValue }}
      </p>
    </div>
  </code>
</template>

<style scoped>
code {
  background-color: #202129;
  border-radius: 4px;
  padding: 20px;
  height: 70px;
  color: white;
  display: flex;
  margin: 0 auto;
  align-items: center;
  width: 350px;
}
</style>Code language: HTML, XML (xml)
```

Next, let’s create a function which will be called when our app loads that will append each character of the`code`variable to the`typeValue`state which has been bound to the UI.

```
<script setup>
// ...

const typeEffect = () => {
  if (typeValue.value.length < code.length) {
    typeValue.value += code.charAt(typeValue.value.length);
    setTimeout(typeEffect, 50);
  }
}
typeEffect()

</script>Code language: HTML, XML (xml)
```

Above we have created a recursion function which will run until all characters of the`code`variable have been appended to the`typeValue`state. We use`setTimeout`to recursively call the`typeEffect`function after 50 milliseconds so that characters won’t be appended instantly in order to create the full feel of a typewriter effect.

Here is the result:

console.log(‘Hello world’) printed with a typewriter style.

Looking good so far. Finally, let’s add the blinking cursor using the following styles:

```
.typingEffect {
  padding-right: 5px;
  border-right: 2px solid white;
  white-space: nowrap;
  animation: blink 1s linear infinite;
}

@keyframes blink {
  0%, 45% {
    border-color: transparent;
  }
  50%, 100% {
    border-color: white;
  }
}Code language: CSS (css)
```

Now, using what we have learned let’s create the “coding” typewriter effect. First, let’s create the typing area and define the text to be used for the typewriter effect:

```
<script setup>
import { ref } from 'vue';
const codeLine1 = "function helloWorld() => {"
const codeLine2 = "console.log('Hello world')"
const codeLine3 = "}"

const typeLine1 = ref('')
const typeLine2 = ref({text: '', state: false})
const typeLine3 = ref({text: '', state: false})

</script>

<template>
  <code class="typingEffect">
    <div>
      <p class="typingEffect__line1">
        {{typeLine1}}
      </p>
    </div>
    <div >
      <p class="typingEffect__line2">
        {{typeLine2.text}}
      </p>
    </div>
    <div >
      <p class="typingEffect__line3">
        {{typeLine3.text}}
      </p>
    </div>
  </code>
</template>

<style scoped>
.typingEffect {
  color: white;
  display: flex;
  flex-direction: column;
  padding: 20px;
  background-color: #202129;
  margin: 0 auto;
  width: 350px;
  height: 120px;
}

.typingEffect__line2 {
  margin-left: 24px;
}
</style>Code language: HTML, XML (xml)
```

Above we have declared`typeLine2`and`typeLine3`as objects in order to add a`state`property which we will use later on to control the typing animation.

Next, let’s create the functions that create the typing animation by appending each character of`codeLine1`,`codeLine2`, and`codeLine3`variables to their respective state.

```
const typeEffect3 = () => {
  typeLine3.value.text += codeLine3.charAt(typeLine3.value.text.length);
}

const typeEffect2 = () => {
  if (typeLine2.value.text.length < codeLine2.length) {
    typeLine2.value.text += codeLine2.charAt(typeLine2.value.text.length);
    setTimeout(typeEffect2, 60);
  }
  if(typeLine2.value.text.length === codeLine2.length && !typeLine3.value.state) {
    setTimeout(typeEffect3, 500)
    typeLine3.value.state = true
  }
}

const typeEffect1 = () => {
  if (typeLine1.value.length < codeLine1.length) {
    typeLine1.value += codeLine1.charAt(typeLine1.value.length);
    setTimeout(typeEffect1, 60)
  }
  if(typeLine1.value.length === codeLine1.length && !typeLine2.value.state) {
    setTimeout(typeEffect2, 800)
    typeLine2.value.state = true
  }
}
typeEffect1()Code language: JavaScript (javascript)
```

Above we have created three functions`typeEffect1`,`typeEffect2`, and`typeEffect3`, each to handle a line of code for the typewriter effect. When the app loads,`typeEffect1`– which is responsible for creating the typing animation for the first line of code – will run. After all characters of the first line of code are displayed, the next function (`typeEffect2`) is called which then calls the next.

Notice we are using`setTimeout`to call the next functions after a few milliseconds of delays. These delays are set to make the typewriter effect look more like how code is actually written.

Next, let’s add the blinking cursor using the following styles:

```
.typingEffect p {
  width: fit-content;
  height: fit-content;
  border-right: 2px solid transparent;
}

.typingEffect__line1 {
  animation: blink 1s 2;
}

.typingEffect__line2 {
  animation: blink 1s 2s 2;
}

.typingEffect__line3 {
  animation: blink 1s 4s infinite;
}

@keyframes blink {
  0%, 45% {
    border-color: transparent;
  }
  50%, 100% {
    border-color: white;
  }
}Code language: CSS (css)
```

Finally, to add syntax highlighting. First, we will add`vue3-highlightjs`to our app by modifying the`main.ts`file to the following:

```
import { createApp } from 'vue'
import App from './App.vue'
import vue3Highlightjs from 'vue3-highlightjs'
import 'highlight.js/styles/dracula.css'

createApp(App).use(vue3Highlightjs).mount('#app')Code language: JavaScript (javascript)
```

Then, we specify where we want to add highlighting using the`v-highlightjs`directive and the language to be highlighted. To do this, modify the template tag in`App.vue`to the following:

```
<template>
  <code class="typingEffect">
    <div v-highlightjs="typeLine1">
      <code class="typingEffect__line1 javascript"></code>
    </div>
    <div v-highlightjs="typeLine2.text">
      <code class="typingEffect__line2 javascript"></code>
    </div>
    <div v-highlightjs="typeLine3.text">
      <code class="typingEffect__line3 javascript"></code>
    </div>
  </code>
</template>Code language: HTML, XML (xml)
```

The syntax highlighting has been added but we will notice that the UI is a bit messy and the blinking cursor is gone. To fix that, add the following styles:

```
.typingEffect code {
  padding: 0;
  background-color: inherit;
}

.typingEffect code {
  width: fit-content;
  height: fit-content;
  border-right: 2px solid transparent;
}Code language: CSS (css)
```

With this, we are done creating the typewriter effect. Try it out in the sandbox:

## Conclusion

In this tutorial, we have learned how to create a typewriter effect using only CSS, and JavaScript. If you’re interested in learning more about creating a great UI with CSS and JavaScript frameworks, check out these blog posts:

- [How to Create Interactive Animated Backgrounds in React with tsParticles](https://coderpad.io/blog/development/interactive-animated-backgrounds-react-tsparticles/)
- [How to Animate A React Application With Framer Motion](https://coderpad.io/blog/development/how-to-animate-a-react-application-with-framer-motion/)
- [How To Build A Draggable Slider With JavaScript](https://coderpad.io/blog/development/how-to-build-a-draggable-slider-with-javascript/)

Taminoturoko Briggs is an enthusiastic software developer and technical writer. Core languages include JavaScript and Python.

## Subscribe for more CoderPad insights

## Trending Articles

Previous slide Next slide [Development

## What is Prompt Engineering?

Introducing AI tools such as ChatGPT and Bard helps increase the efficiency of tasks such as data generation, code generation and completion, text summarization, etc. How were these AI tools trained to answer almost every question you ask them? The answer, prompt engineering, is discussed in this blog post.

Read the post](https://coderpad.io/blog/development/what-is-prompt-engineering/) [Development

## A Guide To Using React’s useCallback() Hook

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we'll dive into React's useCallback() hook, define referential equality and callback functions and how to tie it all together.

Read the post](https://coderpad.io/blog/development/a-guide-to-using-reacts-usecallback-hook/) [Development

## MySQL vs. PostgreSQL: How Do They Compare?

A database is a convenient tool that allows users to access information, maintain records, and apply commonly used operations, such as insertion, modification, deletion, and data organization. Learn about MySQL vs PostgreSQL, their features, advantages, and disadvantages. Finally, check out which one is the best choice for you.

Read the post](https://coderpad.io/blog/development/mysql-vs-postgresql-how-do-they-compare/) [Development

## PostgreSQL LIKE Operator: A Detailed Guide

When using databases, searching for values that match a given pattern is a familiar necessity. Learn how you can retrieve entries with queries including a particular string using Postgres LIKE operator.

Read the post](https://coderpad.io/blog/development/postgresql-like-operator-a-detailed-guide/) [Development

## How To Use DataProvider In TestNG With Examples

When it comes to testing there are many tools and techniques available. In this post, we'll discuss how to use DataProvider with TestNG.

Read the post](https://coderpad.io/blog/development/how-to-use-dataprovider-in-testng-with-examples/) [Development

## How To Get Up And Running With Django Migrations: A Guide

Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.

Read the post](https://coderpad.io/blog/development/how-to-get-up-and-running-with-django-migrations-a-guide/) [Development

## Writing A Parameterized Test In JUnit With Examples

A JUnit parameterized test allows you to decouple data from structure, generating cleaner and more reliable tests. Learn more in this guide.

Read the post](https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/) [Development

## How To Use Assert In JUnit With Examples

The JUnit Assert class is what you use to write unit testing assertions in JUnit. Learn more about it in this guide, full of examples.

Read the post](https://coderpad.io/blog/development/how-to-use-assert-in-junit-with-examples/) [Development

## A Simple Guide To TypeORM: What It Is And How To Use It

Considering current languages have object-oriented programming features, most database management systems are based on the relational model, with tables instead of objects. For these reasons, mapping relational objects is very important in development. In this article, you will learn what TypeORM, one of the main tools used today, is.

Read the post](https://coderpad.io/blog/development/a-simple-guide-to-typeorm-what-it-is-and-how-to-use-it/) [Development

## Using PreparedStatement in JDBC With Examples

In this post, we'll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.

Read the post](https://coderpad.io/blog/development/using-preparedstatement-in-jdbc-with-examples/) [Development

## React vs React Native: The Differences Explained

React and React Native are similar in that they both allow web developers to build applications based on the unique concept of components. But the two frameworks do this in radically different ways. In this post, we cover the key differences between react and react native frameworks, implementation, and which is an appropriate choice.

Read the post](https://coderpad.io/blog/development/react-vs-react-native-the-differences-explained/) [Development

## Logging in Django

The most challenging part of fixing a problem is identifying it. Unfortunately, this statement is exceptionally true when it comes to debugging. Learn how to use the power of logging into your Django applications to improve your debug process in this article.

Read the post](https://coderpad.io/blog/development/logging-in-django/)

## Hire with confidence.

See why engineering teams trust CoderPad to evaluate developers with realistic, AI-ready hiring workflows.

[Request a demo](https://coderpad.io/sales/)
