Scroll Container

A Complete Guide to Modern CSS Scroll Interactions

Understanding Scroll Containers

Scroll containers are fundamental to creating interactive, user-centered web experiences. A scroll container is any element with content that overflows its boundaries, allowing users to access hidden content through scrolling. Modern CSS has evolved to give developers powerful new ways to respond to scroll behavior through container scroll-state queries, enabling responsive interfaces that adapt to how users interact with content.

This evolution represents a significant shift from JavaScript scroll listeners to native CSS solutions. Previously, detecting scroll position required attaching event listeners that could impact performance. Scroll-state queries leverage the browser's compositor thread, providing a more efficient approach to building scroll-aware interfaces.

This guide covers everything you need to know about implementing scroll containers effectively, from basic concepts to advanced techniques that will enhance your UI/UX design implementations. For related scroll techniques, explore our guides on hide scrollbar CSS and custom scrollbars in WebKit.

The Three Pillars of Scroll-State Queries

Scroll-state container queries introduce three powerful descriptors that allow CSS to respond to scroll behavior. These queries are defined in the CSS Conditional 5 Module specification and represent a major advancement in responsive design capabilities.

Scrollable Queries

Test whether a container can be scrolled in a given direction, enabling conditional UI elements based on overflow state. The scrollable query accepts directions like top, bottom, left, right, x, and y, allowing precise control over when elements appear or transform based on scroll position. This is particularly useful for implementing scroll-end event handling and back-to-top buttons.

Snapped Queries

Determine when elements are snapped to scroll snap points along an axis, perfect for creating polished carousel experiences and image galleries. The snapped query works with scroll snap containers to apply styles based on snap state.

Stuck Queries

Detect when position: sticky elements reach their containment boundaries, ideal for implementing sticky navigation and headers. This query enables visual feedback when navigation elements become fixed, creating a professional, polished feel. Pair this with our overscroll behavior guide for complete scroll control.

Each query type serves a distinct purpose in creating responsive scroll interactions that enhance user engagement without sacrificing performance.

Scroll Container Fundamentals

Scrollable Queries

Detect if content overflows and respond to scroll position with CSS-only solutions, eliminating the need for JavaScript scroll listeners.

Snapped Queries

Style elements based on their snap state in scroll snap containers, perfect for creating engaging carousel and gallery experiences.

Stuck Queries

Create polished sticky headers and navigation that respond to scroll position, adding visual feedback when elements become fixed.

Performance Benefits

Browser-optimized scroll state tracking that runs on the compositor thread, avoiding layout thrashing and improving perceived performance.

Syntax and Implementation

To establish a scroll-state query container, use container-type: scroll-state alongside an optional container name for targeted queries:

.scroll-container {
 container-type: scroll-state;
 container-name: my-scroll-area;
}

The query syntax uses @container scroll-state(descriptor: value) format, enabling precise styling based on scroll state. This approach separates the container definition from the query logic, allowing for modular and maintainable stylesheets.

For targeted queries, reference the container by name:

@container my-scroll-area scroll-state(stuck: top) {
 /* Styles applied when stuck at top */
}

This syntax follows the pattern established by existing container queries, making it intuitive for developers already familiar with responsive container queries.

Scroll Container Syntax
1.scroll-container {2 container-type: scroll-state;3 container-name: my-scroll-area;4}5 6@container scroll-state(scrollable: top) {7 /* Can scroll from top */8}9 10@container scroll-state(snapped: y) {11 /* Snapped on y-axis */12}13 14@container scroll-state(stuck: top) {15 /* Stuck at top edge */16}

Practical Examples

Back-to-Top Button

Show a back-to-top button only when the user has scrolled from the top. This pattern improves navigation on long-form content and article pages:

.article-container {
 container-type: scroll-state;
 container-name: article;
}

.back-to-top {
 position: fixed;
 opacity: 0;
 transform: translateY(20px);
 transition: opacity 0.3s, transform 0.3s;
}

@container article scroll-state(scrollable: top) {
 .back-to-top {
 opacity: 1;
 transform: translateY(0);
 }
}

Sticky Navigation with Shadow

Add visual feedback when a sticky header reaches the viewport edge, creating clear visual hierarchy:

.sticky-nav-container {
 container-type: scroll-state;
 position: sticky;
 top: 0;
}

.sticky-nav {
 transition: box-shadow 0.3s ease, background-color 0.3s ease;
}

@container scroll-state(stuck: top) {
 .sticky-nav {
 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
 background: rgba(255, 255, 255, 0.95);
 backdrop-filter: blur(8px);
 }
}

Gallery with Snap Highlighting

Create an interactive carousel that highlights the active item when it snaps into view:

.gallery-container {
 container-type: scroll-state;
 overflow-x: auto;
 scroll-snap-type: x mandatory;
 container-name: gallery;
}

.gallery-item {
 scroll-snap-align: center;
 transition: transform 0.3s, opacity 0.3s;
}

@container gallery scroll-state(snapped: x) {
 .gallery-item {
 opacity: 0.7;
 transform: scale(0.95);
 }
 
 .gallery-item:last-child {
 opacity: 1;
 transform: scale(1.05);
 }
}

These examples demonstrate how scroll containers can create sophisticated user experiences. For modal-specific scrolling solutions, see our guide on preventing page scroll when a modal is open.

Frequently Asked Questions

What is a scroll container?

A scroll container is an element with overflow content that can be scrolled. When combined with container-type: scroll-state, it enables CSS to query and respond to its scroll state, enabling responsive behaviors without JavaScript.

How do scroll-state queries differ from scroll listeners?

Scroll-state queries are evaluated by the browser's compositor thread, making them more performant than JavaScript scroll listeners. They also eliminate complex event handling code and reduce the risk of layout thrashing.

Which browsers support scroll-state queries?

Chrome 133 and later support scroll-state container queries, as announced in the Chrome for Developers blog. Other browsers have ongoing implementations.

Can I use scroll-state queries with position: sticky?

Yes! The stuck query specifically detects when sticky elements reach their containment boundary, making it perfect for implementing polished sticky navigation and headers with visual feedback.

How do scroll-state queries relate to scroll-driven animations?

Scroll-state queries trigger style changes at specific states, while scroll-driven animations create continuous animations based on scroll position. They complement each other for different interaction types.

What are the performance benefits of scroll-state queries?

Scroll-state queries leverage the browser's native scroll state tracking, avoiding JavaScript scroll event listeners that can cause layout thrashing and performance issues. They run on the compositor thread for optimal responsiveness.

Ready to Build Better Scroll Experiences?

Create responsive, user-centered interfaces with modern CSS scroll interactions that engage visitors and improve conversion.

Sources

  1. MDN Web Docs - Using container scroll-state queries - Official documentation for scroll-state container query syntax and usage
  2. Chrome for Developers - CSS scroll-state() - Chrome's official announcement and documentation for scroll-state feature
  3. W3C CSS Conditional 5 Module - Official standards documentation for scroll-state container queries
  4. LogRocket Blog - Implementing scroll-aware UI state with CSS - Practical implementation guide for scroll-driven animations and scroll-aware UI patterns