v149 · CSS

CSS Scroll State Container Queries

Style elements based on their live scroll container state — whether a sticky element is stuck, a snap target is snapped, or content can still be scrolled — all in CSS, no JavaScript polling required.

concepts

  1. Sticky Nav Awareness

    A page header that detects when it is stuck at the top of the viewport and changes its own background, shadow, and text style — purely through @container scroll-state(stuck: top), zero JavaScript.

  2. Snap Carousel

    A horizontal scroll carousel where the currently snapped card scales up and shows its full description — using @container scroll-state(snapped: x) to target the active item without any scroll event listeners.

  3. Scrollable Fade Indicators

    Overflow scroll containers that reveal or hide gradient fade overlays and chevron arrows based on whether there is more content in that direction — driven by @container scroll-state(scrollable: …).

  4. Scroll State Inspector

    An interactive lab with three scroll boxes — sticky, snapping, and overflowing — where every queryable state condition is reflected in real time as a badge using only container query styles.

  5. Sticky Reading Footer

    A blog article inside a scroll container with a footer bar that uses @container scroll-state(stuck: bottom). While reading, the bar is pinned dark to the viewport bottom. When you scroll to the end and the bar reaches its natural position, it turns green — the completion state — with no JavaScript state tracking.

  6. Vertical Story Snap

    A vertical scroll-snap reader with five cards. The currently snapped card uses @container scroll-state(snapped: y) to brighten, reveal body text, and show like and navigation controls. Non-snapped cards are dimmed. Demonstrates the snapped: y block axis — complementing the horizontal snap carousel.

  7. Compound scroll-state queries

    Nested @container scroll-state() rules combined with not let a sticky header respond to multiple simultaneous conditions: stuck at top, plus whether there is still content below. Three contextual badge states — pinned, "↓ more", and "at bottom" — expressed in pure CSS with no JavaScript.

why it shipped

Three recurring UI patterns — sticky headers that change style when pinned, carousels that highlight the active slide, scroll containers with "more content" arrows — have all historically required JavaScript scroll listeners. Those listeners run on the main thread, they must be debounced, and they still produce a one-frame lag. CSS Scroll State Container Queries give the browser a direct hook into the same sticky-pinned, snap-aligned, and scrollable-overflow states that it already tracks internally, letting authors express the response entirely in CSS with no layout thrash and no synchronization bugs.

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗