Sticky Header
A container-type: scroll-state demo — detects when a sticky header is "stuck"
using native CSS where supported, falling back to IntersectionObserver everywhere else.
container-type: scroll-state
Native CSS where supported, IntersectionObserver fallback everywhere else — the badge above tells you which path your browser is taking.
↓ Scroll down to see the header shrinkThe CSS
/* shared "stuck" styles — used by both paths */
header.stuck .logo { font-size: 1rem; }
/* PATH A — native CSS (Chrome 133+) */
@supports (container-type: scroll-state) {
header { container-type: scroll-state; }
@container scroll-state(stuck: top) {
.logo { font-size: 1rem; }
}
}
/* PATH B — JS fallback (everything else) */
/* CSS.supports() check → IntersectionObserver adds .stuck */
const native = CSS.supports('container-type', 'scroll-state');
if (!native) {
const observer = new IntersectionObserver(
([entry]) => header.classList.toggle('stuck', !entry.isIntersecting)
);
observer.observe(sentinel); /* 1px div above the header */
}
Zero JavaScript
Previously you'd need an IntersectionObserver or scroll listener just to know if a sticky header was "stuck". Now CSS handles it.
Native performance
Because it's driven by the browser's layout engine, there's no JS thread overhead or paint jank — transitions run on the compositor.
Container query syntax
It uses the same @container at-rule you already know, extended with scroll-state
queries instead of size queries.
Other states
Beyond stuck: top you can also query stuck: bottom,
stuck: left, stuck: right, and overflowing snap containers.
Browser support
Chrome 133+ ships it. Firefox and Safari are still behind a flag or not yet implemented — check caniuse for the latest.
Combine with size queries
A single element can expose both container-type: size scroll-state so you can mix size
and scroll-state conditions in one rule.
Animate anything
Not just font sizes — transition colours, padding, opacity, transforms, or even grid layouts when the sticky state changes.
Spec background
Part of CSS Containment Level 3. The scroll-state() function is the query mechanism;
stuck is the first supported feature.
Keep scrolling
This page has enough cards to let you see the header fully transition. Scroll back to the top and watch it expand again.