Typewriter
Types the text letter by letter behind a blinking cursor; with phrases it erases each one and types the next.
- enhancer
- loop
- typing
- cursor
- since 0.2
Background Studio: tune it below, then copy the code
Your system asks for reduced motion: the demo shows its final state and nothing moves.
Live demo
Typewriter example
Small files.
Small files.
Code
It follows the controls above: change an option and the code changes with it.
<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>
<p class="demo-big" data-motion="typewriter" data-motion-words="Small files.|Smooth motion.|No framework needed.">Small files.</p>
import { Typewriter } from "./motion/react/Typewriter";
<Typewriter>Your content</Typewriter>
<script setup lang="ts">
import Typewriter from "./motion/vue/Typewriter.vue";
</script>
<template>
<Typewriter>Your content</Typewriter>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "typewriter";
The wrappers: Typewriter.tsx (React, TypeScript) and Typewriter.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
Options
| Attribute | Default | What it does |
|---|---|---|
data-motion-words | auto | More phrases, separated by | |
data-motion-speed | 55 | Time per letter |
data-motion-back | 28 | Time per erased letter |
data-motion-hold | 1800 | Pause on a full phrase |
data-motion-cursor | | | Cursor |
data-motion-color | #f6a04d | Cursor color |
data-motion-loop | true | Keep going |
Accessibility
Every phrase is laid out from the start in one stacked cell, so typing never changes the size of the line. Screen readers hear all phrases once, not the letters; the page holds the first phrase for readers without scripts. Text on screen at load starts complete and only then erases; reduced motion shows the first phrase still. The frame loop and the blinking cursor stop off screen and in hidden tabs.
Size
typewriter.js is 1.6 KB gzip, with text-kit.js 2.6 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.