webdevpuneet.com

Split Text Animation — Free HTML CSS JS Snippet

Split Text Animation · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

<div class="stage">
  <!-- Word-reveal animation -->
  <div class="demo-section">
    <p class="demo-label">Word reveal</p>
    <h2 class="split-words" id="split-words">
      Design with intention
    </h2>
  </div>

  <!-- Character slide-up animation -->
  <div class="demo-section">
    <p class="demo-label">Character slide-up</p>
    <h2 class="split-chars" id="split-chars">
      Build faster
    </h2>
  </div>

  <!-- Line wipe reveal -->
  <div class="demo-section">
    <p class="demo-label">Line wipe</p>
    <div class="line-wipe-wrap">
      <div class="line-wipe" id="line-wipe">Ship with confidence</div>
    </div>
  </div>

  <!-- Scramble-to-reveal -->
  <div class="demo-section">
    <p class="demo-label">Scramble reveal</p>
    <h2 class="scramble-text" id="scramble-text" data-text="Create. Iterate. Ship.">Create. Iterate. Ship.</h2>
  </div>

  <button class="replay-btn" onclick="replayAll()">↺ Replay all</button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Word reveal: overflow:hidden + translateY(110%) + staggered 90ms delay per word
Character slide-up: per-char 40ms delay, rotate(8deg)→0 snap on landing
Line wipe: single translateY(100%)→0 inside overflow:hidden container
Scramble decode: requestAnimationFrame progress-based character locking
Replay button: resets all innerHTML and re-runs all four animations
Dark #0f172a background — split text effects read best on dark surfaces
Spring cubic-bezier(0.16,1,0.3,1) easing matches premium motion design feel
Four independent variants — use any combination in your project

About this UI Snippet

Split Text Animation — Word Reveal, Character Slide-Up, Line Wipe & Scramble Decode

Screenshot of the Split Text Animation snippet rendered live

Split text animations are one of the most in-demand effects on modern landing pages and creative portfolios. They make large display headings (especially gradient text) feel dynamic and intentional — the text appears to emerge from below, one word or character at a time, creating a cinematic reveal that draws the eye and communicates design quality. This snippet provides four distinct split text animation variants: word-by-word reveal, character slide-up with rotation, single-line wipe, and a scramble decode effect — all in plain HTML, CSS, and vanilla JavaScript.

Word-by-word reveal

The text is split into words. Each word is wrapped in two spans: an outer .word-wrap with overflow: hidden, and an inner .word that starts at translateY(110%) — completely below the clip boundary. A CSS @keyframes animation moves each word to translateY(0). Staggered animation-delay (0, 0.09s, 0.18s...) per word creates the sequential reveal. The overflow: hidden on the wrapper makes the word appear to "wipe up" from below rather than fade in.

Character slide-up with rotation

Identical architecture to word reveal but split by character. Each character starts at translateY(110%) rotate(8deg) and animates to translateY(0) rotate(0). The 8° starting rotation adds a slight snap as each character lands upright. The stagger is 40ms per character — tight enough to feel unified, loose enough to see each character individually.

Line wipe reveal

The entire line starts at translateY(100%) inside an overflow: hidden container. A single animation moves the line from below the container to its natural position. No splitting needed — the overflow clip creates the wipe-up effect at the full line level. This is the fastest and most impactful variant for short display text.

Scramble decode

A requestAnimationFrame loop runs for 1200ms. Progress (0 to 1) determines how many characters have been "revealed" to their final value. Unrevealed characters show random characters from a 70-char pool each frame, creating the scramble effect. As progress increases, more characters lock into their final positions from left to right.

Combining multiple variants for a sequence

Chain all four variants with increasing base delays for a coordinated reveal sequence: splitWords(headline, 0); splitChars(subheading, 0.6); wipeReveal(tagline, 1.0); scramble(cta, 1.4). The scramble variant is the same effect as the standalone text scramble. The delays create a natural reading order — headline first, supporting text follows. Use this pattern for full-screen hero sections like the word-flip hero where each text element appears sequentially.

Step by step

How to Use

  1. 1
    Click "↺ Replay all" to see all four animations restartThe word reveal, character slide-up, line wipe, and scramble decode all run in sequence with staggered starts. Each animation has a different timing — observe how each creates a different visual impression.
  2. 2
    Use the word reveal for hero headlinesCall splitWords(el, baseDelay) where el is your headline element. The function splits text into words, wraps each in overflow:hidden spans, and applies staggered CSS animation delays. Works for any text length.
  3. 3
    Use character split for short impact textCall splitChars(el, baseDelay) for 2-4 word text. Best for short, punchy text — "Bold. Fast. Free." The character rotation adds energy. Avoid for long text where 40ms×40 chars = 1.6s total before the last character lands.
  4. 4
    Trigger animations on scroll with IntersectionObserverWrap the replayAll() call in an IntersectionObserver: const obs = new IntersectionObserver(([e]) => { if(e.isIntersecting) { replayAll(); obs.disconnect(); } }, { threshold: 0.3 }); obs.observe(document.querySelector(".stage")).
  5. 5
    Change animation timing and easingUpdate cubic-bezier(0.16,1,0.3,1) in the @keyframes CSS for different feels. This is a spring-style ease-out. Use ease for softer, linear for mechanical. Change 0.6s duration to 0.4s for snappier or 1s for more dramatic reveals.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component using useEffect to trigger on mount or scroll, or "Tailwind" for a React + Tailwind CSS version.

Real-world uses

Common Use Cases

Hero section headline animations on landing pages
The word-by-word reveal is the dominant text animation on premium SaaS landing pages. Large display headlines (48-80px) with word splits feel cinematic and signal design investment. Trigger on page load for above-the-fold text, on scroll for below-the-fold sections.
Portfolio and agency site dramatic text reveals
Creative agencies and designers use split text animations to make their own sites feel as polished as their client work. The character slide-up with rotation creates the highest visual drama for 2-3 word impact statements.
Product launch countdown and announcement pages
For coming-soon and launch pages, the scramble decode creates tension and excitement — text appears to resolve from chaos to order. Pair it with a countdown timer for a dramatic pre-launch page.
Onboarding flow step headlines with scroll triggers
Each onboarding step has a headline that reveals as the step becomes visible. The line wipe variant is fastest to implement and most subtle — appropriate for functional UI rather than pure marketing pages.
Study overflow:hidden clip and CSS animation stagger techniques
The word and character reveal patterns both use the same overflow:hidden + translateY trick. The stagger uses CSS animation-delay computed from index. These two techniques — clip boundary + staggered delay — are the foundation of most premium text animation implementations.
Replace GSAP SplitText for simple text reveals
GSAP SplitText is a premium paid plugin. This snippet covers the most common use cases (word split, character split, line wipe) in under 80 lines of vanilla JavaScript. For projects that only need simple text reveals, this zero-dependency implementation has identical visual output.

Got questions?

Frequently Asked Questions

The .word-wrap (or .line-wipe-wrap for the line variant) has overflow: hidden. Inside it, the text element starts at transform: translateY(110%) — 110% of the element height, positioning it completely below the container's bottom edge. Because overflow is hidden, the text is invisible. As translateY animates to 0, the text rises from below the invisible clip boundary into view. The result looks like the text is wiping up from the baseline — a much more polished effect than a simple fade-in.

Use IntersectionObserver: const elements = document.querySelectorAll(".split-words, .split-chars"); const obs = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { if (entry.target.classList.contains("split-words")) splitWords(entry.target); else splitChars(entry.target); obs.unobserve(entry.target); } }); }, { threshold: 0.3 }); elements.forEach(el => obs.observe(el)). The obs.unobserve() prevents re-animating on scroll back.

Add: if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { document.getElementById("split-words").textContent = "Design with intention"; return; } at the top of replayAll(). For CSS: @media (prefers-reduced-motion: reduce) { .word, .char { animation: none; transform: none; opacity: 1; } .line-wipe { animation: none; transform: none; } }. This makes all text immediately visible without animation for users who have enabled the system accessibility setting.

Click "JSX" to download. Run the split functions in a useEffect on mount: useEffect(() => { splitWords(wordsRef.current, 0); splitChars(charsRef.current, 0.4); ... }, []). Use useRef for each animation target element. For scroll-triggered animations, add an IntersectionObserver inside the useEffect. Return a cleanup: return () => cancelAnimationFrame(scrambleFrame) to cancel any ongoing rAF loop when the component unmounts.