webdevpuneet.com

Scroll Crossword Fill Reveal — Free HTML CSS JS Snippet

Scroll Crossword Fill Reveal · Scroll · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="hint">Scroll ↓ to fill in the puzzle</div>
<section class="puzzle-section">
  <div class="grid" id="grid">
    <div class="cell" data-n="1"><span class="num">1</span><span class="letter">S</span></div>
    <div class="cell" data-n="2"><span class="letter">C</span></div>
    <div class="cell" data-n="3"><span class="letter">R</span></div>
    <div class="cell" data-n="4"><span class="letter">O</span></div>
    <div class="cell" data-n="5"><span class="letter">L</span></div>
    <div class="cell" data-n="6"><span class="letter">L</span></div>
    <div class="cell blank"></div>
    <div class="cell" data-n="7"><span class="num">2</span><span class="letter">G</span></div>
    <div class="cell" data-n="8"><span class="letter">S</span></div>
    <div class="cell" data-n="9"><span class="letter">A</span></div>
    <div class="cell" data-n="10"><span class="letter">P</span></div>
    <div class="cell blank"></div>
    <div class="cell" data-n="11"><span class="num">3</span><span class="letter">T</span></div>
    <div class="cell" data-n="12"><span class="letter">R</span></div>
    <div class="cell" data-n="13"><span class="letter">I</span></div>
    <div class="cell" data-n="14"><span class="letter">G</span></div>
    <div class="cell" data-n="15"><span class="letter">G</span></div>
    <div class="cell" data-n="16"><span class="letter">E</span></div>
    <div class="cell" data-n="17"><span class="letter">R</span></div>
  </div>
  <div class="clues">
    <p><strong>1 across</strong> — moves a page vertically</p>
    <p><strong>2 across</strong> — the space between two points</p>
    <p><strong>3 across</strong> — what starts an animation</p>
  </div>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), 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

Plain CSS grid layout — no canvas, no absolute-positioned letter tiles
One scrubbed GSAP timeline drives every cell's pop-in and highlight flash together
back.out(2) ease gives each letter a satisfying slight-overshoot "snap into place"
Blocked/blank squares are a simple CSS class, filtered out of the animated cell list
Brief backgroundColor flash on each cell simulates a pen just having filled it in
Fully reversible — scrolling up empties the grid in reverse stagger order
Classic crossword palette: navy grid lines, white cells, pale blue fill-in flash
Short, precise ScrollTrigger start/end window keeps the reveal tied to the grid entering view

About this UI Snippet

Scroll Crossword Fill Reveal — Staggered Grid Reveal with a Scrubbed Timeline

Screenshot of the Scroll Crossword Fill Reveal snippet rendered live

A puzzle-style scroll reveal where a CSS grid of crossword cells fills in one at a time as the section scrolls into view, each cell popping into place and briefly flashing a highlight color like a pen just wrote it in. Pair with Scroll Text Clip Reveal for a complementary letter-driven effect, or Scroll Reveal Grid patterns for a simpler staggered reveal.

A CSS grid, not a canvas

The puzzle is a plain display: grid of .cell divs with grid-template-columns: repeat(6, 44px). Filled black squares between words are separate .cell.blank divs that stay opaque from the start — no JavaScript needed to distinguish playable cells from blocked ones, it's a CSS class.

One scrubbed timeline, one tween per cell

gsap.utils.toArray('.cell:not(.blank)') collects every playable cell in document order. A single timeline loops over them, giving cell i a start position of i * 0.06 on the shared timeline. Each cell gets a fromTo popping it from scale(0.5)/opacity:0 to full size with a back.out(2) ease for a slight overshoot, like a letter snapping into its box.

The "just filled in" flash

Right after each cell's pop-in tween, two more tweens at the same and nearby timeline positions animate backgroundColor from white to a pale blue and back to white — a quick highlight flash that reads as "this cell was just written," independent of the scale/opacity pop.

Why start/end target only the grid's entrance

The ScrollTrigger's start: 'top 75%' / end: 'top 5%' window is deliberately short — just the distance it takes the grid to scroll from mostly-below-viewport to near the top. Because it's all one scrubbed timeline, scrolling back down below the start point resets every cell back to invisible/unscaled, and scrolling past the end point leaves the completed grid fully filled.

Reversibility for free

Because every letter's appearance is driven by scroll-mapped timeline position rather than a one-shot trigger, scrolling up "erases" the puzzle in the same staggered order it filled in, which is what makes this feel fundamentally different from a fire-once IntersectionObserver reveal.

Step by step

How to Use

  1. 1
    Scroll the grid into viewScroll down until the crossword grid enters the upper part of the viewport — cells pop in one by one with a brief blue highlight flash.
  2. 2
    Scroll back upThe grid empties out in the same staggered order, confirming the effect is fully reversible.
  3. 3
    Change the puzzle contentEdit the letters inside each .letter span and the data-n clue numbers in the HTML panel to spell a different word or phrase.
  4. 4
    Adjust the grid shapeChange grid-template-columns (currently repeat(6, 44px)) in the CSS panel to make a wider, narrower, or differently-sized grid.
  5. 5
    Tune the stagger speedChange the 0.06 multiplier in pos = i * 0.06 in the JS panel to make cells fill in faster or slower relative to each other.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for React, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Puzzle or word-game landing page
Showcase a crossword, word-game, or trivia app with a playful scroll-triggered demonstration of the grid filling in.
Educational vocabulary or spelling reveal
Repurpose the grid to spell out a key term or concept as students scroll through a lesson page.
Brand name or tagline reveal
Use the crossword-fill motion as a distinctive way to spell out a brand name, product name, or short tagline on a hero section.
Learn staggered grid animation with a scrub timeline
Study how per-item start positions (i * constant) inside one scrubbed timeline produce a stagger that stays perfectly reversible.
Print or publishing brand scroll section
A natural fit for newspaper, magazine, or puzzle-book brands wanting a scroll moment that nods to their print heritage.

Got questions?

Frequently Asked Questions

Blank squares use an extra .blank CSS class that sets opacity: 1 and a dark background from the start. The JS collects animated cells with gsap.utils.toArray(".cell:not(.blank)"), so blanks are simply skipped by the query selector.

They are two separate tweens placed at the same (or a slightly offset) timeline position: one animates scale/opacity for the "appearing" motion, another animates backgroundColor for the "just written in" highlight. Layering simple tweens like this is easier to tune than one complex keyframe animation.

Every cell's appearance is a tween inside one scrubbed timeline mapped to a specific scroll range. Scrubbing the timeline backward runs those tweens in reverse, so cells shrink back to invisible in the same order they appeared.

Yes — add more .cell divs to the grid and increase grid-template-columns' repeat count in the CSS. The JS automatically staggers however many non-blank cells exist, no changes needed there.

The reveal is meant to complete quickly as the grid scrolls into the upper viewport, similar to a staggered card-grid reveal — pinning isn't needed because the grid doesn't need to hold the viewport's attention beyond its own entrance.