CSS Scroll State Queries
CSS Scroll State Container Queries let you style elements based on their scroll-related state—whether they're stuck, snapped, or scrollable—directly from CSS, no JavaScript required.
Experimental Feature: CSS Scroll State Queries require Chrome 133+. This demo uses @supports for progressive enhancement.
/* Define scroll-state container */
.container {
container-type: scroll-state;
}
/* Query stuck, snapped, or scrollable states */
@container scroll-state(stuck: top) { /* styles */ }
@container scroll-state(snapped: x) { /* styles */ }
@container scroll-state(scrollable: bottom) { /* styles */ }Stuck State
Query when a sticky element is stuck to an edge. Perfect for adding shadows or visual feedback to sticky headers.
.sticky-container {
container-type: scroll-state;
}
.sticky-header {
position: sticky;
top: 0;
}
@container scroll-state(stuck: top) {
.header-content {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
background: hsl(var(--card));
}
}Scroll within the container to see the navbar background appear when stuck
scroll-state(stuck: top)
Triggers instantly when stuck
scroll-driven animation
Animates over 0-50px scroll distance
Snapped State
Query when a scroll-snap item is snapped to its alignment point. Great for highlighting the active item in carousels.
.carousel {
scroll-snap-type: x mandatory;
}
.carousel-item {
container-type: scroll-state;
scroll-snap-align: center;
}
@container scroll-state(snapped: x) {
.card {
opacity: 1;
transform: scale(1);
}
}Scroll horizontally to snap between cards—the snapped card will be highlighted
Scrollable State
Query when a container has scrollable overflow in a direction. Use it to show scroll shadows or hide scroll-to-top buttons when not needed.
.scroll-container {
container-type: scroll-state;
}
@container scroll-state(scrollable: top) {
.shadow-top { opacity: 1; }
.scroll-to-top { opacity: 1; }
}
@container scroll-state(scrollable: bottom) {
.shadow-bottom { opacity: 1; }
}Add or remove content to see the scroll shadows and scroll-to-top button appear