Scroll Color Sections — Free GSAP ScrollTrigger Color Shift

Scroll Color Sections · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Palette data attributes
data-bg and data-fg per section.
Center-crossing toggle
Theme switches when a section owns center.
Smooth crossfade
Body color tweens between palettes.
Flicker-safe
overwrite auto cancels stale tweens.
Reversible
Colors revert on scroll-up automatically.
Readable text
Foreground tints with each background.
One wiring loop
Every section uses the same trigger logic.
CSS fallback
Body transition backs up the tween.

About this UI Snippet

Scroll Color Sections — Crossfade the Page Theme as You Scroll

Screenshot of the Scroll Color Sections snippet rendered live

Scroll color sections is the effect where the entire page background smoothly shifts color as you move from one full-screen section to the next, each section owning its own palette — the immersive technique on product and portfolio sites that makes scrolling feel like changing rooms. This snippet builds it with GSAP and ScrollTrigger (from a CDN), plus plain HTML and CSS.

Palettes as data

Each section declares its theme with two attributes: data-bg for the background and data-fg for the text color. The script reads these when the section becomes active, so the palette lives in the markup, not the code — adding a section or recoloring one is a two-attribute change. One loop wires every section to the same logic.

Toggle on center crossing

For each section a ScrollTrigger is created with start: 'top center' and end: 'bottom center', so the trigger is "active" precisely while that section spans the middle of the viewport. Its onToggle callback checks self.isActive and themes the page to that section's colors. Using the viewport center as the boundary means the new palette takes over exactly when the new section dominates the screen — the most natural moment to switch — and reverts as you scroll back up.

Crossfade, not cut

The actual color change is a GSAP tween on document.body's backgroundColor and color with a short duration, so the page eases between palettes instead of snapping. overwrite: 'auto' cancels any in-flight color tween when a new one starts, which prevents flicker if you scroll quickly through several sections — the new target simply takes over from wherever the color currently is. A CSS transition on the body is also present as a fallback.

Why ScrollTrigger toggles fit this

This is a discrete state effect (which section is in charge), not a continuous scrub, so onToggle with active/inactive states is the right tool — far cleaner than computing scroll math by hand or stacking IntersectionObservers with threshold tuning. ScrollTrigger handles the enter/leave boundaries and the reverse direction automatically.

Tinted text for contrast

Because each palette sets both background and foreground, text stays readable on every theme — a light foreground on the dark plum, a warm one on amber. Pairing the two colors per section is what keeps contrast correct as the whole page recolors.

Customizing it

Add sections with their own palettes, change the crossfade duration, switch the boundary (e.g. top 60%), or also tween an accent variable for buttons and links. Pair it with a scroll parallax layers scene, a scroll zoom hero, or reveal on scroll content.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to reason through the toggle logic in isolation. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why onToggle with self.isActive is the right primitive here instead of a continuous scrub, and why start: 'top center' / end: 'bottom center' is what makes the "owns the theme" boundary land precisely at the viewport's middle. The same assistant is useful for optimizing it — asking whether overwrite: 'auto' fully prevents flicker on very fast scroll-throughs of many sections, or whether tweening a CSS custom property instead of document.body directly would scope the recolor more safely in a larger app. It's also useful for extending the effect: ask it to also crossfade an accent color used by buttons and links, tie in a background image crossfade alongside the color, or drive the palette list from a CMS array instead of inline data attributes. 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 color sections" effect in plain HTML, CSS, and JavaScript using GSAP and its ScrollTrigger plugin (load both from a CDN, no build step).

Requirements:
- A sequence of full-viewport-height sections, each carrying its own background color and foreground text color as data attributes on the section element (not hardcoded in JS or CSS), so adding a themed section is purely a markup change.
- For every section, create a ScrollTrigger whose start is 'top center' and whose end is 'bottom center', so the trigger is considered active only while that specific section spans the vertical middle of the viewport.
- Use the trigger's onToggle callback (checking self.isActive) — not scrub — to decide when a section takes ownership of the page theme, since this is a discrete state change (which section is "in charge") rather than a continuously interpolated scroll value.
- When a section becomes active, animate document.body's backgroundColor and color to that section's data attributes with a short GSAP tween (a few tenths of a second), and set overwrite: 'auto' on that tween so a fast scroll through multiple sections cancels any in-flight color tween rather than queuing or flickering between them.
- Add a plain CSS transition on the body's background-color and color as a non-JS fallback layer underneath the GSAP tween.
- Confirm scrolling back up reverts the theme correctly through the same triggers with no separate "reverse" code — ScrollTrigger's own active/inactive toggling in both directions must be what drives it.
- Do not use IntersectionObserver or manual scroll-offset calculations for this — the section-owns-the-viewport-center logic must come from ScrollTrigger's start/end/onToggle model.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

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 JSFive full-screen color sections render.
  3. 3
    Scroll downThe page background crossfades per section.
  4. 4
    Scroll back upThe palettes revert in reverse order.
  5. 5
    Recolor a sectionEdit its data-bg and data-fg attributes.
  6. 6
    Add a sectionDrop in another with its own palette.

Real-world uses

Common Use Cases

Story scrolls
Set moods in a scroll pin story.
Product pages
Section themes around feature cards.
Portfolios
Recolor between scroll parallax layers scenes.
Onboarding
Tint steps of an onboarding tour.
Brand reels
Pair with a scroll zoom hero.
Reveals
Theme behind reveal on scroll blocks.
Related: Scroll Chat Story
See the Scroll Chat Story for a related scroll pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Each section has a ScrollTrigger with start: top center and end: bottom center, so it is active precisely while it spans the middle of the viewport. Its onToggle fires and themes the page when isActive becomes true, so the new palette takes over exactly when the new section dominates the screen, and reverts as you scroll back up.

The change is a GSAP tween on the body's backgroundColor and color with a short duration, so the page eases between palettes. overwrite: auto cancels any in-flight color tween when a new one starts, preventing flicker during fast scrolls — the new target takes over from the current color. A CSS transition on the body acts as a fallback.

This is a discrete state effect — which section currently owns the theme — not a continuous value, so onToggle with active and inactive states is the right tool. ScrollTrigger handles the enter and leave boundaries and the reverse direction automatically, which is cleaner than manual scroll math or threshold-tuned IntersectionObservers.

Each section defines both data-bg and data-fg, and the tween sets the body's color alongside its background. Pairing a foreground with each background — light text on dark plum, warm text on amber — keeps contrast correct as the whole page recolors, rather than leaving the text fixed against a changing backdrop.

Render sections with data-bg/data-fg, then in a mount effect register ScrollTrigger and loop the sections to create triggers whose onToggle tweens the document body. Return a cleanup that reverts the GSAP context so triggers are removed on unmount. The CSS ports unchanged; you can also tween a CSS variable instead of the body for scoped theming.