CSS Scroll‑Driven Animations Playground - Online Demo
Create animations that progress with scroll position. Experiment with animation‑timeline and view‑timeline. Cutting‑edge CSS.
UD5 Toolkit
Live demo & compatibility test for CSS @container scroll-state() — detect stuck & snapped elements
Scroll down — when a sticky header gets stuck at top, the @container scroll-state(stuck: top) query activates.
This section introduces the concept of scroll-state container queries. The header above uses position: sticky; top: 0;.
When you scroll this container, the header will stick to the top edge. The container has container-type: scroll-state enabled.
The CSS @container scroll-state(stuck: top) rule detects this sticky state and applies highlight styles automatically — no JavaScript required (in supported browsers).
The scroll-state container query observes the scrollport for sticky-positioned descendants. When any position: sticky element becomes physically stuck to the specified edge, the query matches.
This is a boolean state query — it's either true or false. You can combine it with other container queries using and / or logic.
Key insight: the query fires for any sticky child inside the container, not just a specific one.
Imagine a table of contents sidebar: when a sticky header is active, you could dim non-relevant items or highlight the current section.
Another use case: sticky table headers that change appearance when "locked" — adding a shadow, changing background, or revealing action buttons.
Scroll-state queries bring these interactions to CSS, eliminating the need for complex IntersectionObserver setups.
As of late 2024, scroll-state container queries are available in Chrome Canary behind the Experimental Web Platform Features flag.
Safari and Firefox are actively working on implementation. This tool helps you test whether your current browser supports the feature natively.
For production, always provide a JavaScript fallback using IntersectionObserver or scroll event listeners.
Scroll-state container queries unlock new possibilities for state-driven styling without JavaScript. Combined with size container queries, they form a powerful responsive design toolkit.
Try the snap demo in the next column, and check the FAQ below for deeper insights.
Scroll to snap cards into place — @container scroll-state(snapped: block) detects when a child is aligned.
Sticky Detection
Snap Detection
Container Declaration
scroll-state container type. This enables purely CSS-driven reactions to scroll interactions without JavaScript.
chrome://flags/#enable-experimental-web-platform-features flag is enabled. Safari and Firefox have expressed interest and are tracking the specification, but native support is not yet available in stable releases. Use @supports (container-type: scroll-state) for feature detection.
stuck: top refers to the physical top edge regardless of writing mode. stuck: block-start is logical — it refers to the block-start edge, which depends on the writing mode (top in horizontal-tb, right in vertical-rl). For most English-language sites, they behave identically. Using logical properties (block-start, block-end, inline-start, inline-end) makes your styles more portable across different writing modes.
scroll-state(stuck: top) query matches if any sticky-positioned descendant inside the container is currently stuck to the top edge. You don't need to target a specific element — the query acts as a global state flag for the entire scroll container. This makes it perfect for patterns like "is any section header currently pinned?" to adjust a table of contents or toolbar.
scroll-state(snapped: block) detects whether the container's scroll position is currently aligned to a snap point in the block direction. For scroll-snap-type: y mandatory, the scroll position will always snap (so the query may always match once scrolling stops). For proximity snapping, the query only matches when close enough to a snap point. You can query snapped: x, snapped: y, snapped: block, snapped: inline, or snapped: both.
IntersectionObserver with a rootMargin that matches the sticky offset, or compare the sticky element's getBoundingClientRect().top against its container's top. For snap detection, listen to the scrollend event and check if scrollTop aligns with any child's offsetTop. Apply CSS classes (.is-stuck, .is-snapped) to replicate the container query behavior. This demo uses exactly this fallback approach for browsers without native support.
container-type: scroll-state size; (or use separate container names) to query both scroll state and dimensions. However, note that container-type: scroll-state alone does not enable size queries — you need to explicitly include size or inline-size. You can also nest containers: an outer container tracks size, while an inner one tracks scroll-state, giving you fine-grained control.
| Query Type | Syntax | Detects | Requires |
|---|---|---|---|
stuck: top |
@container scroll-state(stuck: top) |
Sticky element pinned to top edge | position: sticky; top: 0; on child |
stuck: bottom |
@container scroll-state(stuck: bottom) |
Sticky element pinned to bottom edge | position: sticky; bottom: 0; on child |
stuck: left / right |
@container scroll-state(stuck: left) |
Sticky element pinned horizontally | position: sticky; left: 0; on child + horizontal scroll |
snapped: block |
@container scroll-state(snapped: block) |
Child aligned to block-axis snap point | scroll-snap-type on container + scroll-snap-align on children |
snapped: inline |
@container scroll-state(snapped: inline) |
Child aligned to inline-axis snap point | Horizontal scroll-snap-type |
snapped: both |
@container scroll-state(snapped: both) |
Child aligned in both axes simultaneously | 2D scroll-snap-type |
Create animations that progress with scroll position. Experiment with animation‑timeline and view‑timeline. Cutting‑edge CSS.
Hover over tiles to see every CSS cursor value in action. Quick visual reference for choosing the right UI feedback.
Browse a curated set of button hover animations. See each effect live and copy the CSS. Minimalist collection.
Hover over tiles to see every CSS cursor value in action. Quick visual reference for choosing the right UI feedback.
See every touch point with coordinates, radius, and force on your mobile device. Debug gestures with live overlay.
Flip a virtual coin to make a decision or settle a dispute. Realistic animation and fair random outcome. Simple, fast, and always available.
Click to get a random element and a short story about its discovery and uses. Fascinating science.
Click for a random general knowledge question, then reveal the answer. Covers science, history, pop culture.
Play the classic Snake game inside your browser. Arrow keys to move, eat the apple, grow longer. High score tracked locally.
Unified input demo: see pressure, tilt, and type from any pointer. Compare pointerType values. Essential for drawing apps.
Click to see a random English word with its definition and an example sentence. Expand your vocabulary daily.
Browse a beautifully designed periodic table with electron shell visualization and key facts. Click any element to learn more. Offline ready.
Write a fragment shader and see the result rendered on a full‑screen quad. For WebGL learners. Local compilation.
Generate a random 4‑panel comic sketch with simple stick figures and funny dialogue. Just for laughs. Canvas.
Fetches a random Wikipedia article summary via API. Read interesting facts. Simple knowledge discovery tool. No data collected.
Spin a wheel or randomize to get a chemical element with fascinating facts and description. Great for kids.
Pick a language and get a random useful travel phrase with pronunciation. For fun language learning. Static data.
Get a catchy, Product Hunt‑style tagline for your side project. Like 'Uber for left shoes'. Instant creativity.
See a clip of a famous artwork and choose the correct title. Art history fun. Local images.
Easily convert between kilograms, pounds, ounces, stones, and more. Supports both metric and imperial weight units. Instant and private conversions.
Play Hangman where the words are element names. Learn the periodic table while having fun. High score localStorage.
Click to get a randomly generated unique abstract icon (geometric pattern). Download as SVG. For placeholder avatars and designs.
A short lyric is shown, guess the song title. Score tracking. Multiple genres. Local database of snippets. No playback needed.
Get a random famous movie quote along with the film name and year. Test your movie knowledge. Static data, no API.
Generate a realistic‑sounding dinosaur name and see a fun description. Perfect for kids and writers.
Generate a single line from famous public‑domain poems. Great for creative writing prompts or daily inspiration.
Get a common English idiom with its meaning and example. Perfect for ESL learners. Local collection.
Paste a cURL command and convert it to a fetch() call in JavaScript, Python requests, or Go net/http. Save time.
Enter a keyword or author to find classic quotes from public domain works. Inspiration tool.
Get a random quote from Shakespeare's works with play and character attribution. Copy in beautiful typography.