AI CSS Animations

Guides · · Maxwell Prehoda

11 Text Reveal Animation Examples: Lines, Words, Letters and Scroll

Most text reveals are the same two steps. First split the text into lines, words or characters, each in its own element. Then animate those pieces in sequence, usually sliding each one up from behind a clipping mask (`overflow: hidden` on a wrapper) with a short stagger and a strong ease-out. Lines read as editorial and calm, words as confident, characters as playful; scroll-linked versions tie the reveal to the reader's position instead of a timer.

Below are 11 examples: the splitting libraries most sites use, the scroll-driven CSS that now does some of it natively, a React component for scroll reveals, and three of ours. Every entry has a live demo you can copy, and each third-party entry says when the demo is our pure-CSS version of the idea.

1. GSAP SplitText: Best for editorial line reveals on marketing sites

Platform: JavaScript, GSAP (free, backed by Webflow)

Design that earns attention.
Live from our directory: Line Mask Reveal. Copy the HTML and CSS →

SplitText is the best-known text splitter on the web, and it got much better in GSAP 3.13: a rewrite that the docs say made it about half the size and added 14 features. The three that matter most for reveals are `mask`, which wraps each line, word or character in a clipping element so pieces can slide up from nowhere; `autoSplit`, which re-splits when fonts finish loading or the line widths change; and `onSplit`, which re-syncs your animation after a re-split so a resized window never leaves you with broken lines.

It is also accessible by default: with `aria: "auto"` the parent gets an `aria-label` with the full text and the split pieces are hidden from screen readers, so nobody hears a headline spelled out letter by letter. GSAP's pricing page now lists the whole library, SplitText included, as free for everyone thanks to Webflow's support.

Our Line Mask Reveal below is the pure-CSS version of SplitText's masked line reveal: each line slides up out of an invisible mask, one after another.

Watch out for: Line splits depend on the final font and width. Split after fonts load (autoSplit does this) or the lines you animate will not match the lines the reader sees.

GSAP pricing: now free ↗

2. Splitting.js by Stephen Shaw: Best for CSS-driven staggers with a tiny script

Platform: JavaScript, about 1.5 KB gzipped, MIT

Welcome!
Live from our directory: Letters Rise. Copy the HTML and CSS →

Splitting.js takes a different approach: it splits words and characters into spans and adds CSS variables and data attributes, then leaves the animation to your stylesheet. Each character knows its index, so a stagger becomes one line of CSS, a transition delay of the index times 30 ms, and you can change the whole effect without touching JavaScript.

At about 1.5 KB gzipped it is the lightest option here, and its maintainers, Stephen Shaw and Christopher Wallis, publish a CodePen collection of demos. It also splits grids, cells and images, which makes it useful beyond headlines.

Our Letters Rise below uses exactly that idea in plain CSS: every span carries its index in a custom property, so the delay is one `calc()` and adding letters needs no new CSS.

Watch out for: Character spans break kerning and ligatures, and some scripts (Arabic, Devanagari) cannot be split into characters without breaking how they render. Split by words for those languages.

GitHub ↗Demo collection ↗

3. anime.js splitText: Best for open source projects that want splitting and timing in one

Platform: JavaScript, anime.js v4.1 and later, MIT

Soft focus
Live from our directory: Letter by Letter Blur In Text. Copy the HTML and CSS →

anime.js, Julian Garnier's MIT-licensed animation engine (over 74k GitHub stars), added `splitText` in v4.1.0, and since v4.2.0 you can import it on its own from `animejs/text`. It splits by lines, words and characters, with options for including spaces, wrapping pieces and cloning them, which is how you build roll-over reveals where a copy slides in as the original slides out.

The docs call it an accessible text utility, and pairing it with anime.js's own stagger helpers gives you a full reveal system with no paid tier anywhere in the chain.

Our Letter by Letter Blur In below is a CSS take on a character reveal: letters sharpen out of a blur one after another, with a long overlap that gives a soft gradient of focus.

Watch out for: Blur on every character is expensive. Use it for a short headline, not a paragraph, and animate opacity and transform for anything longer.

anime.js on GitHub ↗

4. Motion splitText: Best for teams already paying for Motion+

Platform: JavaScript, Motion+ (paid), about 0.7 KB

Every word counts
Live from our directory: Word by Word Text Animation. Copy the HTML and CSS →

Motion's `splitText` wraps text in spans and returns arrays of `chars`, `words` and `lines`, adding about 0.7 KB to your bundle and applying ARIA attributes so the text stays readable for assistive technology. You then animate the pieces with Motion's `animate` and `stagger`, or with CSS or any other library.

Its docs example is the canonical character reveal: opacity from 0 to 1 and a 10px rise, one second each, with a 50 ms stagger. That stagger value is a good default for characters; for words, double it.

Our Word by Word Text Animation below is the word version in pure CSS: each word slides up out of its own hidden slot, tilted slightly, one after another.

Watch out for: splitText is not in the free motion package; it needs a Motion+ membership. If that is the only Motion+ feature you need, a free splitter does the same job.

5. SplitType by Luke Peavey: Best for existing projects that already depend on it

Platform: JavaScript, open source

Meet halfway
Live from our directory: Split Text Reveal Effect. Copy the HTML and CSS →

SplitType is a small library that splits text into lines, words and characters, and its README says it was inspired by GSAP's SplitText and works with any animation library. Before SplitText became free it was a common no-cost alternative, so you will still meet it in tutorials and older projects.

It is worth knowing so you can recognise it in an existing codebase, and worth comparing against the newer options before you start something new.

Our Split Text Reveal Effect below shows a different kind of split, done in CSS: the top half of the word slides in from the left and the bottom half from the right, meeting in the middle.

Watch out for: The repository's last code push was in December 2023. With GSAP SplitText now free and anime.js shipping its own splitter, check maintenance before choosing it for new work.

6. Magic UI Text Reveal: Best for React landing pages with a scroll-read manifesto

Platform: React + Motion, shadcn registry, MIT

Center stage
Live from our directory: Spotlight Text Reveal. Copy the HTML and CSS →

Magic UI's Text Reveal fades text in as you scroll down the page. Its source shows how it works: a section 200vh tall holds a sticky block, the text is split into words, and each word's opacity is mapped from 0 to 1 over its own slice of the scroll progress, on top of a copy of the text at 30 percent opacity so the reader always sees the full shape of the paragraph.

This is the pattern behind the big statement paragraphs on many product sites: one sentence that brightens word by word as you read it. The ghost layer is what keeps it usable, because nothing is ever fully hidden.

Our Spotlight Text Reveal below uses the same ghost idea on a timer: the text waits as a faint ghost until a soft spotlight sweeps across it.

Watch out for: A 200vh scroll for one sentence is a lot of scrolling. Keep scroll-linked reveals to one per page and make sure the text is readable at every scroll position.

7. CSS scroll-driven reveals with view(): Best for reveal-on-scroll with no JavaScript

Platform: CSS, animation-timeline (limited availability)

Reveal
Live from our directory: Reveal Up On Scroll. Copy the HTML and CSS →

`animation-timeline: view()` ties an ordinary keyframe animation to an element's progress through the scrollport. The animation sits at 0 percent when the element first appears at one edge and reaches 100 percent when it leaves the other, and insets such as `view(block 50% 10%)` narrow that range. For text, that means a headline can wipe or rise into place exactly as it scrolls into view, and reverse when you scroll back, without an IntersectionObserver.

Pair it with `animation-range` to finish the reveal early (by the time the line is a third of the way up) so people never read half-revealed text.

Our Reveal Up On Scroll below wipes into view from the bottom edge as it scrolls in, with a clip-path inset that shrinks from 100 percent.

Watch out for: MDN marks view() as limited availability. Put the hidden starting state inside @supports (animation-timeline: view()) so browsers without it show the text normally.

8. Bramus' scroll-driven animations demos: Best for learning scroll timelines with visual tools

Platform: Free demos, tools and course, Apache 2.0

Fade into view
Live from our directory: Fade In Left to Right Text. Copy the HTML and CSS →

Bramus, a Chrome Developer Relations engineer, built the reference site for scroll-driven animations: about 17 demos with CSS and Web Animations API versions, visualisers for scroll and view timelines and their ranges, a free 10-part video course and a DevTools extension for debugging. It is handcrafted HTML, CSS and JavaScript under Apache 2.0.

The range visualiser is the part to use for text. Drag the entry and cover ranges until the reveal completes while the line is still comfortably in the reading zone, then copy the values.

Our Fade In Left to Right Text below is a reveal that works well on a scroll timeline: a feathered gradient mask slides across, so there is no hard clip line.

Watch out for: Scroll-linked text that keeps animating while people read causes motion sickness for some. Respect prefers-reduced-motion by showing the final state.

9. Our Text Reveal Animations collection: Best for pure-CSS reveals with no splitting script

Platform: Motions directory, free, pure CSS Ours

Unveiled
Live from our directory: Wipe Reveal. Copy the HTML and CSS →

Every reveal in this collection is HTML and CSS with no JavaScript: masks, clip-path wipes, staggered letters and word slots, each with a `prefers-reduced-motion` guard and custom properties for colour and size. The demo is Wipe Reveal: a clip-path inset uncovers the text from left to right, and the text itself never moves.

Pick a CSS reveal when the text is fixed and short (a hero headline, a section title, a button label) and you would rather not ship a splitter. Reach for SplitText or anime.js when the text comes from a CMS and line breaks are unknown.

Watch out for: Hand-split spans need an aria-label on the parent and aria-hidden on the pieces, exactly as the libraries do, or screen readers read the word in fragments.

10. Our Highlighter Sweep: Best for emphasising one phrase inside body copy

Platform: Motions directory, free, pure CSS Ours

The part that matters
Live from our directory: Highlighter Sweep. Copy the HTML and CSS →

A translucent highlighter stroke draws in behind the words after a short delay, as if someone marked the important line. It plays once and stays.

This is the reveal for content, not for headlines: the text is readable from the first frame, and the motion only adds emphasis to the claim you want remembered. It works well on pricing pages, testimonials and long-form articles where a full reveal would get in the way of reading.

Watch out for: Check the highlight colour against the text colour. A bright marker behind light text can drop contrast below 4.5:1.

11. Our Decrypt Text Effect: Best for security, developer and AI product headlines

Platform: Motions directory, free, pure CSS Ours

ACCESS GRANTED
Live from our directory: Decrypt Text Effect. Copy the HTML and CSS →

Each character spins through random symbols, then locks onto the real letter with a flash, left to right with a little jitter. The symbols are an animated `content` value on a pseudo-element, so it needs no script.

It is a reveal with a meaning: data being decoded. Use it where that metaphor fits, such as a security product, a developer tool or an AI feature. For typing-style reveals see our typewriter effect examples.

Watch out for: Screen readers should hear the word, not the symbols. Our snippet puts the real text in an aria-label on the parent; keep that pattern if you change the markup.

How to choose a text reveal animation

Match the split to the tone

Lines are calm and editorial: use them for long headlines and section intros (Line Mask Reveal). Words are confident and readable: use them for short statements (Word by Word). Characters are playful and attention-grabbing: keep them for a word or two (Letters Rise). Scroll-linked words suit one manifesto paragraph per page.

Match it to your stack

Known, short text: pure CSS from our Text Reveal Animations collection. CMS text with unknown line breaks: GSAP SplitText (free) with mask and autoSplit, or anime.js splitText (MIT). CSS-first teams: Splitting.js for the index variables. React: Magic UI's Text Reveal for scroll, or Motion+ splitText if you already have it. Native scroll reveals: animation-timeline: view() behind @supports.

Match it to the reader

Finish fast: the whole reveal should complete in under a second, with staggers of about 30 to 60 ms per character and 80 to 120 ms per word or line. Never hide text people need to read for longer than that. Keep the full text available to screen readers with aria-label on the parent, and under prefers-reduced-motion show the text immediately or with a plain fade.

Reveal your next headline properly

Take your hero headline and split it by line. Wrap each line in an element with `overflow: hidden`, start the inner span at `translateY(100%)`, and animate it to 0 over 600 ms on a strong ease-out with a 100 ms stagger. Put the full sentence in an aria-label. That is the reveal on most of the sites you admire.

Copy a ready one from the Text Reveal Animations collection, or describe your headline and get production-ready CSS from the creator. For the broader family of type motion see our text animation examples and the post on kinetic typography with AI.

A prompt to start from
Make a pure CSS line-by-line text reveal for a two-line hero headline.
Each line slides up from translateY(100%) inside an overflow-hidden wrapper over 600 ms with cubic-bezier(0.16, 1, 0.3, 1), staggered 100 ms.
The parent carries an aria-label with the full sentence and the line spans are aria-hidden.
Play once on load; under prefers-reduced-motion show the text immediately with a 150 ms fade.

Make your own with AI →

Common questions

How do you make a text reveal animation in CSS?

Wrap each line or word in an element with overflow: hidden, put the text in an inner span that starts translated down by 100 percent, and animate it to 0 with a staggered animation-delay. For a wipe instead of a slide, animate clip-path: inset() from 0 100% 0 0 to 0. Neither needs JavaScript if the text is fixed.

Is GSAP SplitText free?

Yes. GSAP's pricing page says the whole library, including SplitText, is 100 percent free for all users thanks to Webflow's support. SplitText was rewritten in GSAP 3.13 to be about half the size, with new options such as mask, autoSplit and onSplit.

Are split text animations bad for accessibility?

They can be if screen readers read each fragment separately. Put the full text in an aria-label on the parent and hide the pieces with aria-hidden, which GSAP SplitText does by default with aria: auto. Also respect prefers-reduced-motion and keep reveals short so text is never hidden for long.

How do you reveal text on scroll without JavaScript?

Use animation-timeline: view() on the text with a normal @keyframes reveal, and animation-range to control when it starts and finishes. MDN marks view() as limited availability, so wrap the hidden starting state in @supports (animation-timeline: view()) and let other browsers show the text normally.

What stagger should I use for a text reveal?

Roughly 30 to 60 ms between characters and 80 to 120 ms between words or lines. Motion's docs example uses 50 ms per character. Keep the total under about a second so readers are not waiting for the end of the sentence.

Sources