Scroll Word Wheel — Free GSAP Headline Snippet

Scroll Word Wheel · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Scroll-turned wheel
The scrollbar rotates the headline word.
Em-based mask
A 1.24em window needs no JS measuring.
Exact notches
yPercent steps land on word boundaries.
Hold-then-snap
Words dwell, then click like a slot drum.
Baseline-true
Moving words share the sentence baseline.
Drum-edge fades
Gradient masks suggest a curved wheel.
Count-aware
Scroll budget scales with the word list.
Per-word accent
Each word brings its own color.

About this UI Snippet

Scroll Word Wheel — A Rotating Headline Word Turned by Scroll

Screenshot of the Scroll Word Wheel snippet rendered live

The scroll word wheel is the "Built for designers / founders / marketers…" headline — but instead of auto-rotating on a timer, the wheel is turned by the scrollbar. Each segment of scroll snaps the masked word column one notch to the next word, and scrolling up spins it back. Giving the rotation to the reader turns a passive header into a scrubbed reveal of who the product serves. This snippet builds it with GSAP ScrollTrigger (from a CDN) and a masked column.

A one-line-tall mask hides all but the current word

The wheel is an inline-block .sww-wheel sized to exactly 1.24em tall with overflow: hidden — a viewport one line high. Inside it, the word list is a flex column where every <em> occupies that same 1.24em. Only one word can be visible at a time; the rest wait above or below the mask. Sizing in em keeps the mask correct at every clamp() font size without any JS measurement.

yPercent moves in exact word-height notches

Each notch tweens the list to yPercent: -(100 / COUNT) × i. Because yPercent is relative to the *list's* own height, and each word is exactly 1/COUNT of that height, every step lands pixel-perfectly on the next word — no hardcoded pixel offsets to break when the font size changes responsively.

Hold-then-snap pacing instead of continuous slide

Rather than one linear tween (which would show word edges scrolling constantly), the timeline places a short 0.35-duration power2.inOut tween just before each integer position: the wheel *holds* on a word for most of its segment, then snaps decisively to the next. Under a scrub, that means each word gets real reading time and transitions feel mechanical-in-a-good-way, like a slot drum clicking between detents. The pacing lives entirely in the position/duration math — i − 0.35 — so retuning the dwell time is one number.

Baseline alignment keeps the sentence intact

The static "Built for" and the wheel sit in a flex row aligned to baseline, and the wheel uses vertical-align: bottom so the moving words share the sentence's baseline. Word-wheel implementations commonly float half a pixel off the line; locking heights and line-heights to the same 1.24em is what keeps every word sitting exactly where static text would.

Gradient fades sell the drum

Two thin pseudo-element gradients at the mask's top and bottom fade incoming and outgoing words into the background, suggesting a curved drum edge — a purely decorative touch that reads as depth without any 3D transforms.

Scroll distance scales with the word count

end is COUNT × 55%, so each word owns the same scroll budget however many you add; the notch loop derives everything else from COUNT. Add a sixth word by adding one <em> — no other edits.

Per-word color via a custom property

Each word carries its own --wc accent, so the highlight color changes with the audience being named — a small cue that each notch is a distinct claim.

Customizing it

Edit the words (keep them short enough for your narrowest viewport), tune the dwell via the 0.35 constants, or drop the pin and trigger it inside a hero. For the timer-based version see the word flip hero; pair with a scroll typewriter or hand off to a scroll letter stagger headline.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to work out the yPercent notch math or the hold-then-snap timeline positions by hand. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why each notch is placed at timeline position i minus 0.35 instead of at a plain integer, and why yPercent (rather than a pixel translateY) is used to land on exact word boundaries. The same assistant can help optimize it — for instance checking whether the end value's COUNT times 55 percent scroll budget still feels right once the word list grows past ten entries, or whether the gradient fade pseudo-elements should be simplified for very small type sizes. It is just as useful for extending the effect: ask it to make the wheel loop continuously instead of stopping on the last word, add a subtle 3D rotateX tilt to sell the drum illusion more convincingly, or let a click on the wheel jump directly to a specific word instead of only scroll-driven notches. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll word wheel" headline in plain HTML, CSS, and JavaScript using GSAP and its ScrollTrigger plugin (load both from a CDN, no build step).

Requirements:
- A headline made of static leading text followed by a masked "wheel" element sized to exactly one line's height in em units (not pixels) with overflow: hidden, so only one word from an inner vertical list is visible at a time.
- The inner word list must be a flex column where every word element is locked to that same one-line em height, so that moving the list by whole multiples of that height lands exactly on word boundaries regardless of the responsive font size.
- Register a single GSAP timeline on a ScrollTrigger with pin: true and scrub, whose end scroll distance scales with the number of words (for example word count times a fixed percentage), so adding or removing words automatically adjusts how much scroll distance the whole effect consumes.
- For each word transition, add a short discrete tween (not one continuous linear tween across the whole timeline) that moves the list by yPercent equal to minus 100 divided by the word count, times the word's index, using an in-out easing curve — and position each of these short tweens just before its corresponding integer timeline position, so the wheel visibly holds on each word for most of its scroll segment and then snaps quickly to the next, like a mechanical drum clicking between detents.
- Add two thin gradient-fade pseudo-elements at the top and bottom edge of the mask to visually suggest a curved drum rather than a flat hard-edged window.
- The whole sequence must reverse cleanly when scrolling back up, spinning the wheel backward through the words in the same notch-by-notch fashion.

Step by step

How to Use

  1. 1
    Add the GSAP CDNsInclude gsap and ScrollTrigger from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSThe masked wheel renders showing its first word.
  3. 3
    Scroll into the stageIt pins; the wheel holds, then snaps a notch.
  4. 4
    Keep scrollingEach segment clicks to the next colored word.
  5. 5
    Scroll back upThe wheel spins backward through its words.
  6. 6
    Edit the wordsAdd an em with its own --wc; pacing auto-scales.

Real-world uses

Common Use Cases

Audience headlines
Name every persona you serve; expand each with sticky scroll features.
Hero sections
A scrubbed alternative to the auto-playing word flip hero.
Capability lists
Cycle verbs — build, ship, scale — before a scroll reveal grid.
Campaign taglines
Snap through slogan variants, then a scroll curtain reveal transition.
Typing alternatives
Where per-character motion fits better, use the scroll typewriter.
Stat pairings
Match each audience with a number via count up.

Got questions?

Frequently Asked Questions

The wheel is an overflow-hidden inline-block exactly 1.24em tall — a one-line viewport — and every word in the inner column is locked to that same height and line-height. Only the word aligned with the window is visible; the rest sit above or below the mask. Because everything is em-based, the mask stays exact at every responsive font size.

Each step tweens the column to yPercent −(100/COUNT) × i. yPercent is relative to the list's own height, and each word is exactly 1/COUNT of it, so steps land on word boundaries by construction — no pixel constants that would break when clamp() changes the font size or a different typeface changes metrics.

The timeline places a short 0.35-unit power2.inOut tween just before each integer position, so under the scrub the wheel dwells on a word for most of its segment and then clicks over. Continuous sliding would show word edges constantly and make everything half-readable; hold-then-snap gives each word genuine reading time, like a slot drum settling into detents.

Edit the em elements — each carries its own --wc accent color. COUNT is read from the DOM, the trigger's end scales at 55% of viewport height per word, and the notch loop derives every position from COUNT, so a sixth word needs zero JS edits. Keep words short enough to fit your narrowest viewport since the wheel is white-space: nowrap.

Render the words from an array and build the timeline in a mount effect — useEffect, onMounted, or ngAfterViewInit — inside gsap.context scoped to the stage ref, reverting on cleanup so the pin unregisters on unmount. Derive COUNT from the array, not the DOM. The mask is two Tailwind-friendly rules (overflow-hidden plus a fixed em height); keep the em heights in a style tag or arbitrary values.