v157 · css · scroll snap

Scroll snap for single-axis scroll containers

A single-axis scroll container — overflow: auto clip — scrolls on one axis and merely clips on the other. Until now it still captured descendant snap areas on both axes, including the axis it cannot scroll, so the trapped alignment could never do anything. With this feature the container consumes only the axis it scrolls; the other axis propagates up to the nearest ancestor scroller that can handle it. A vertical feed can finally snap to the cards inside its horizontal carousels.

concepts

  1. Propagation probe

    Measure the behaviour change directly. A control scroller proves that programmatic scrolls re-snap in this browser, then the same probe runs against a snap area trapped inside an overflow: auto clip carousel — if the outer scroller snaps to it, per-axis propagation is active. Includes a live computed-overflow readout of the prerequisite.

  2. Multi-carousel feed

    The explainer’s canonical use case: a streaming-style vertical feed of horizontal carousels. Horizontal card pagination works in every current Chrome; the vertical card-edge snap is what this feature adds, and the page measures honestly which of the two your browser is doing — plus the wrapper-based workaround you ship today.

  3. clip vs hidden migration

    overflow-y: hidden keeps trapping snap areas forever — it is still a 2D scroll container. clip is what propagates. Side-by-side scrollers, a computed-value inspector showing whether your browser still coerces clip to hidden, and the scroll-snap-align: start none per-axis opt-out.

  4. Writing-mode hand-off

    scroll-snap-align is logical; scrollers are physical. Flip a snap container between horizontal-tb and vertical-rl and watch the same block-axis alignment move between physical axes — the resolution step that propagation hands off as a physical requirement to ancestors.

why it shipped

Single-axis scroll containers landed first (see its own demo portfolio) and already taught position: sticky to track a different ancestor scroller per axis. Scroll snap was the loose end: a carousel declaring overflow-x: auto; overflow-y: clip swallowed its cards’ vertical scroll-snap-align even though it can never scroll vertically. This feature applies the same per-axis model to snap — consume the scrollable axis, propagate the clipped one — so the multi-carousel feed pattern works without wrapper hacks.

Behaviour only changes where clip stays clip. Pre-single-axis browsers silently converted a scrollable/clip pair to hidden, which is a two-axis scroll container that legitimately traps both axes — that compatibility story is the migration concept.

references