All components Zyqor Components

Component · split-text

Split text

Headlines that rise line by line out of a mask, letters that flip up, and a paragraph that lights up word by word as you read it. Accessible, and re-measured so lines never break wrong.

Vanilla JS2.6 KBFonts-readyReduced motionScreen reader safe
anim: rise · lines

Maps for people who walk slowly.

anim: chars · letters

Hand-drawn. Printed in Porto.

anim: scrub · scroll the page

Every Slowmap sheet is drawn by one cartographer who walked the route first. We mark benches, bakeries, steep steps and the quiet way round, and we leave out the noise a phone map can't.

Use it

Copy the folder split-text/ (the .js and .css files) into your project. No build step and no framework.

Behaviour

  • Lines are measured after the web fonts load and again on width changes (not on phone address-bar resizes), so a line never breaks in the wrong place.
  • One level of inline markup is kept: an italic serif word stays italic after the split.
  • Screen readers read the sentence once from a visually hidden copy; the animated copy is aria-hidden.
  • prefers-reduced-motion: text is shown at once, no movement, the scrub paragraph is full ink.
  • Scroll scrub uses one passive scroll listener and one rAF for every paragraph on the page.

Credits

  • Line-mask reveals are a staple of award sites such as FORMAT by Obys (Awwwards SOTD Oct 19 2026) and Emotion Agency (SOTD Oct 22 2026). The scroll reading highlight is common on product pages. Written from scratch; no code or text copied.
  • Slowmap is a fictional brand for this demo.
<link rel="stylesheet" href="split-text.css">

<h1 data-split="lines">Maps for people who <span class="serif">walk</span> slowly.</h1>
<p data-split="chars">Hand-drawn. Printed in Porto.</p>
<p data-split="words">Long paragraph that lights up word by word as it scrolls.</p>

<script type="module" src="split-text.js"></script>

<!-- by hand -->
<script type="module">
  import { splitText, play } from './split-text.js';
  splitText(el, { by: 'lines', anim: 'rise' });
  play(el); // replay the reveal
</script>
OptionDefaultWhat it does
data-splitlineslines (mask rise per line), chars (letters flip up) or words (scroll scrub).
data-split-animby typeForce an animation: rise, chars or scrub.
data-split-repeatoffHide again when the text leaves the screen, so it replays on the way back.
--st-delay0msCSS variable: delay before the first line or letter starts.
--li / --ci / --wiset by JSIndex of each line, letter, word; use them for your own stagger maths.