Typography and Text Effects

Typewriter text animation

Use CSS step animation to simulate text appearing one character at a time with a blinking cursor.

HTMLCSSAnimationText
With JavaScript enabled, you can edit, run, and save this example. The fixed source is as follows:
<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Typewriter text animation</title>
  <style>
    * { box-sizing: border-box; }
    body { min-height: 100vh; margin: 0; display: grid; place-items: center; padding: 22px; color: #342b26; font-family: Georgia, "STSong", serif; background: #d9cfbd; background-image: repeating-linear-gradient(0deg, rgba(77,59,43,.04) 0 1px, transparent 1px 5px); }
    .paper { position: relative; width: min(820px, 100%); min-height: 470px; padding: clamp(38px, 8vw, 82px); border: 1px solid #b8aa95; background: #f5eddf; box-shadow: 0 24px 60px rgba(57,43,31,.2); transform: rotate(-.4deg); }
    .paper::before { content: ""; position: absolute; top: 0; bottom: 0; left: clamp(20px, 5vw, 48px); width: 1px; background: rgba(190,75,64,.25); }
    .date { color: #8b7362; font: 700 11px/1 "Courier New", monospace; letter-spacing: .18em; }
    h1 { margin: 40px 0 22px; font-size: clamp(31px, 6vw, 58px); line-height: 1.3; font-weight: 500; }
    .typed-line { display: inline-block; max-width: 100%; overflow: hidden; border-right: .08em solid #bd493c; white-space: nowrap; vertical-align: bottom; animation: typing 4s steps(16, end) .5s both, caret .75s step-end infinite; }
    p { max-width: 580px; margin: 0; color: #78685d; font-size: 16px; line-height: 1.9; }
    .signature { margin-top: 54px; color: #bd493c; font: italic 24px/1 "STKaiti", "KaiTi", serif; transform: rotate(-3deg); }
    .seal { position: absolute; right: clamp(24px, 6vw, 64px); bottom: 46px; display: grid; width: 62px; height: 62px; place-items: center; border: 3px double #bd493c; color: #bd493c; font: 700 18px/1 "STKaiti", "KaiTi", serif; opacity: .72; transform: rotate(7deg); }
    @keyframes typing { from { width: 0; } to { width: 16em; } }
    @keyframes caret { 50% { border-color: transparent; } }
    @media (max-width: 560px) { .typed-line { white-space: normal; animation: reveal 1.2s ease both; border: 0; } .paper { min-height: 520px; } }
    @keyframes reveal { from { opacity: 0; transform: translateY(8px); } }
    @media (prefers-reduced-motion: reduce) { .typed-line { width: auto; animation: none; border: 0; } }
  </style>
</head>
<body>
  <main class="paper">
    <span class="date">A LETTER FROM SUMMER · 2026</span>
    <h1><span class="typed-line">May every departure bring a new answer.</span></h1>
    <p>Some scenery is not at the destination, but in those moments when the direction changes on a whim. Leave a little blank space in the plan and let summer finish the rest of the story itself.</p>
    <div class="signature">For You on the Way</div>
    <div class="seal" aria-hidden="true">See<br>Mountain</div>
  </main>
</body>
</html>
Page feedbackFound an issue or have suggestions for improvement?
Feedback features need to be used in the online version

Please enable JavaScript in the online version before submitting; local features of the current tool or example are not affected.

Go to the online version for feedback