What Makes Scroll State Queries Valuable
Traditional responsive design responds to viewport dimensions, but scroll state queries respond to user behavior. When a user scrolls down through a long article, you might want to hide the navigation bar to maximize content space. When they begin scrolling back up, the navigation reappears--exactly when they need it.
These interactions once required complex JavaScript event listeners and scroll calculations. Now, with container scroll state queries, such behaviors can be achieved with pure CSS, improving performance and reducing maintenance overhead.
Key capabilities include:
- Responding to scroll direction (up, down, left, right)
- Detecting when sticky elements become fixed
- Styling based on scroll snap positions
- Showing/hiding elements based on scrollable content
Container scroll state queries are part of a broader evolution in modern web development that emphasizes CSS-native solutions over JavaScript-heavy implementations. Combined with related techniques like scroll snap and scroll indicator patterns, these queries enable sophisticated scroll-responsive interfaces without compromising performance.
Understanding Container Scroll State Queries
Container scroll state queries are a type of container query introduced in CSS Conditional Level 5. Unlike traditional container queries that respond to size dimensions, scroll state queries allow you to apply styles to descendant elements based on the container's scroll state.
This includes whether the container is partially scrolled, snapped to a scroll snap container ancestor, or positioned via position: sticky and stuck to a boundary of a scroll container ancestor.
The Browser-Managed State Advantage
One of the most significant aspects of scroll state queries is that the browser manages the underlying state. The browser tracks whether an element is stuck to an edge, whether it's snapped within a scroll snap container, and whether scrolling is possible in a given direction.
This tracking happens internally, with CSS queries providing access to this information without requiring JavaScript event listeners.
Establishing a Scroll State Container
.container {
container-type: scroll-state;
container-name: my-container;
}
The distinction between container types is important to understand. A container with container-type: scroll-state only tracks scroll state--it doesn't automatically become a scroll container itself. If you need both scroll state tracking and scrolling behavior, ensure the element also has overflow settings that create a scroll container, such as overflow: auto or overflow: scroll.
For developers working with complex interfaces, understanding how scroll state interacts with overscroll behavior and scrollbar customization is essential for creating seamless user experiences.
The Three Query Types
Scroll state queries include three distinct types, each designed to address different aspects of scroll behavior.
scrollable Query
The scrollable query tests whether a container's scrolling ancestor can be scrolled in a given direction via user-initiated scrolling. It answers: "Is there overflowing content in this direction that the user can scroll to?"
Values: top, inline-end, y, x, block, inline
snapped Query
The snapped query determines whether a container is or will be snapped to a scroll snap container ancestor along a given axis. This enables styling changes when scroll snap behavior takes effect.
Values: x, y
stuck Query
The stuck query addresses sticky positioning. When an element with position: sticky reaches its sticky boundary, the stuck query can trigger style changes.
Values: top, bottom, left, right
For practical examples of these queries in action, explore our CSS techniques library for more frontend development patterns. Additionally, understanding ARIA roles like slider role and landmark role helps ensure your scroll-responsive interfaces remain accessible to all users.
1/* Show back-to-top link only when scrolled away from top */2@container scroll-state(scrollable: top) {3 .back-to-top {4 opacity: 0;5 pointer-events: none;6 }7}8 9@container scroll-state(scrollable: top: false) {10 .back-to-top {11 opacity: 1;12 pointer-events: auto;13 }14}1.sticky-header {2 container-type: scroll-state;3 position: sticky;4 top: 0;5 transition: box-shadow 0.3s ease;6}7 8@container scroll-state(stuck: top) {9 .sticky-header {10 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);11 }12}The scrolled Query: Direction-Based Styling
The scrolled query represents the newest addition, introduced in Chrome 144. This powerful query detects the direction of the most recent relative scroll.
Direction Values
- Physical:
top,right,bottom,left - Logical:
block-start,inline-start,block-end,inline-end - Axis-based:
x,y,block,inline - Special:
none(no scroll yet)
Hidey Bar Pattern
One common use case is hiding navigation when scrolling down and revealing it when scrolling up. This "hidey bar" pattern maximizes content space while maintaining easy navigation access when users change direction. The scrolled query enables this behavior entirely in CSS, without requiring JavaScript scroll event handlers.
This pattern demonstrates the power of user-centered design principles where interfaces adapt to user intent rather than requiring explicit user actions to reveal or hide elements. When implementing such patterns, ensure you also consider accessibility guidelines to maintain usability for keyboard and screen reader users.
1html {2 container-type: scroll-state;3}4 5header {6 position: fixed;7 inset: 0 0 auto;8 transition: translate 0.2s;9 translate: 0 0;10}11 12/* Hide when scrolling down */13@container scroll-state(scrolled: bottom) {14 header {15 translate: 0 -100%;16 }17}18 19/* Show when scrolling up */20@container scroll-state(scrolled: top) {21 header {22 translate: 0 0;23 }24}Best Practices for Implementation
Progressive Enhancement
Always use @supports queries for graceful degradation:
@supports (container-type: scroll-state) {
.navigation {
container-type: scroll-state;
}
@container scroll-state(stuck: top) {
.navigation {
/* Enhanced styles */
}
}
}
Browsers that don't support container-type: scroll-state will ignore both the supports check and the scroll state queries, falling back to baseline styles that work without the enhanced behavior.
Performance
Scroll state queries are managed by the browser and optimized for performance. Unlike JavaScript scroll event listeners that fire continuously during scrolling, scroll state queries only trigger when state actually changes. This makes them significantly more performant than equivalent JavaScript implementations.
Focus on properties that can be efficiently animated: transforms, opacity, and color changes. Avoid expensive property changes or complex layout calculations within query blocks.
Accessibility
Respect user motion preferences:
@media (prefers-reduced-motion: no-preference) {
header {
transition: translate 0.2s ease;
}
}
Always test your scroll-responsive interfaces with reduced motion preferences enabled to ensure functional behavior without potentially disorienting animations. For comprehensive accessibility testing, review our guide on web accessibility with the accessibility API.
Practical patterns for implementing scroll-responsive interfaces
Scroll-Responsive Navigation
Navigation that hides when scrolling down to maximize content space, and reveals when scrolling up.
Sticky Section Headers
Section headers that transform when they become stuck--adding backgrounds, borders, or context indicators.
Interactive Carousels
Galleries where the active item highlights and inactive items fade when snapped into view.
Scroll Progress Indicators
Progress bars or indicators that show scroll position and remaining content.
Frequently Asked Questions
Sources
- Chrome for Developers - CSS scroll-state() - Official Google documentation covering stuck, snapped, and scrollable queries with Chrome 133 implementation details.
- MDN Web Docs - Using container scroll-state queries - Comprehensive MDN reference with syntax documentation and examples.
- W3C CSS Conditional 5 Draft - Scroll State Container Queries - Official specification for the feature.
- Una Kravets - scroll-state(scrolled) - Advanced use cases and practical demos for scroll direction detection.