::scroll-marker

Create accessible, CSS-only navigation for scrollable content including carousels and tab interfaces with native keyboard and screen reader support.

Understanding ::scroll-marker

Web interfaces increasingly rely on smooth, accessible navigation through scrollable content. For years, developers have used JavaScript to create carousel controls, tab indicators, and scroll position markers. The ::scroll-marker pseudo-element introduces a native CSS solution that provides accessible navigation without scripting.

This powerful feature automatically generates scroll markers for each child element within a scroll container, complete with built-in ARIA semantics and keyboard navigation support. The result is cleaner code, better accessibility, and improved performance. Our web development team leverages these modern CSS capabilities to build interfaces that work across devices and accessibility tools.

What ::scroll-marker Does

The ::scroll-marker pseudo-element represents a visual marker tied to a scrollable item within a scroll container. When you activate a scroll marker, the browser scrolls the container to display the associated content item. Each child element of a scroll container can have a ::scroll-marker, and these markers are automatically organized into a ::scroll-marker-group pseudo-element.

Unlike traditional navigation approaches that require JavaScript event handlers, ::scroll-marker provides declarative navigation that the browser handles natively. This means scroll markers work with keyboard navigation, respond to focus management, and integrate with screen readers automatically. The pseudo-element can be styled like any other element, allowing developers to create visual indicators that match their design system.

This approach treats navigation as part of the scroll container's rendering rather than as separate interactive elements. The scroll markers exist as pseudo-elements, meaning they don't add to the DOM tree directly but are rendered as part of the scroll container's presentation. When a user interacts with a marker, the browser handles the scrolling behavior natively, including scroll snapping if configured.

For teams building modern web applications, ::scroll-marker represents a significant step forward in creating interfaces that work across devices and accessibility tools without the complexity of custom JavaScript navigation components. Whether you're building an e-commerce product carousel or a documentation sidebar, this CSS feature provides a foundation for intuitive navigation experiences.

Key Capabilities

What ::scroll-marker brings to your interfaces

Native Accessibility

Automatic tab and tablist ARIA roles with built-in keyboard navigation and screen reader support.

CSS-Only Navigation

Create carousels, tabs, and scroll indicators without writing a single line of JavaScript.

Browser Integration

Leverages native scrolling behavior including scroll-snap for polished user experiences.

Semantic Markup

Markers are pseudo-elements that don't clutter the DOM while maintaining proper semantics.

Required Properties and Syntax

The content Property Requirement

Every ::scroll-marker must have a content property set to a non-none value. Even if you want an invisible marker, you must explicitly declare content: "" to generate the marker. Without this declaration, no marker appears for the element. This requirement ensures that scroll markers are intentional and explicitly defined rather than accidentally generated.

The content property can contain various values depending on your needs. For visual indicators like carousel dots, you might use an empty string and style the marker with background, border, and dimensions. For text-based markers like tabs, you can include actual content text. You can even use attr() to pull content from data attributes, making it easy to generate markers from HTML attributes.

/* Create an invisible marker */
element::scroll-marker {
 content: "";
}

/* Create a text-based marker */
element::scroll-marker {
 content: "Tab 1";
}

/* Use data attributes for dynamic content */
element::scroll-marker {
 content: attr(data-tab-label);
}

scroll-marker-group: The Essential Container Property

The scroll-marker-group property must be set on the scroll container for any markers to appear. This property accepts two values: before and after, which position the marker group relative to the scroll container's content. The default value of none means no marker group is generated.

/* Markers appear before the content (good for tabs) */
.scroll-container {
 scroll-marker-group: before;
}

/* Markers appear after the content (good for carousels) */
.scroll-container {
 scroll-marker-group: after;
}

Choosing between before and after depends on your visual design. For carousel indicators that appear below image sliders, use after so the markers appear after the content. For tab interfaces where navigation appears above content, use before. The value should match the visual layout of your interface to maintain logical correspondence between markers and their associated content.

A working scroll marker implementation requires three declarations: the content property on each ::scroll-marker, the scroll-marker-group property on the scroll container, and overflow properties that create a scrollable container. Without overflow: auto or overflow-x: auto, the element isn't a scroll container and won't generate markers.

Complete Carousel Implementation
1.carousel {2 display: flex;3 overflow-x: auto;4 scroll-snap-type: x mandatory;5 scroll-marker-group: after;6}7 8.carousel-item {9 flex: 0 0 100%;10 scroll-snap-align: start;11}12 13.carousel-item::scroll-marker {14 content: "";15 width: 12px;16 height: 12px;17 border-radius: 50%;18 border: 2px solid #333;19}20 21.carousel-item::scroll-marker:target-current {22 background: #333;23}

Accessibility Features

Built-in ARIA Semantics

Scroll markers automatically receive tab and tablist ARIA roles, making them accessible to screen readers without additional markup or JavaScript. When a scroll container has a scroll-marker-group, it gains tablist semantics, and each marker receives tab semantics with appropriate aria-selected states that reflect the current scroll position.

This automatic accessibility means that scroll markers meet WCAG guidelines for keyboard operability and screen reader compatibility out of the box. Users can navigate using standard keyboard shortcuts, and screen readers announce markers with their position and selection state. The accessibility is inherent to the feature rather than added as an afterthought. Our accessibility-focused web development practices ensure that all interfaces meet these standards.

Screen Reader Announcements

When focused on a scroll marker, screen readers announce the marker's position within its group (such as "tab, 1 of 5") along with any text content in the marker. You can provide alternative text for screen readers using the content property's alternative text syntax:

/* Visual label differs from screen reader announcement */
element::scroll-marker {
 content: "●" / "Slide 1";
}

This allows visual designs to differ from what screen readers announce without compromising either experience. The announcement includes the selection state ("selected" for the current tab) and the total number of tabs in the group.

Keyboard Navigation Support

Scroll markers support full keyboard navigation without any additional code:

  • Tab to the marker group
  • Use arrow keys to navigate between markers
  • Activate with Enter or Space
  • Wrapping at group boundaries

The arrow key navigation wraps around at the ends of the group, matching established conventions for tab interfaces. This behavior comes built-in, requiring no JavaScript event handlers or focus management code.

Combining with Scroll Snapping

Scroll markers work seamlessly with CSS Scroll Snap, creating polished carousel and sliding panel experiences. The scroll-snap-type property on the container controls snap behavior, while scroll-snap-align on children determines how they snap into view. When users interact with scroll markers, the browser respects these snap settings, providing smooth, controlled scrolling that feels natural and predictable.

Browser Support and Feature Detection

Current Browser Support

As of early 2025, ::scroll-marker has limited browser support. The feature works in Chromium-based browsers including Chrome and Edge, but does not function in Firefox or Safari. This limited availability means you should implement progressive enhancement, using scroll markers for supported browsers while providing fallback navigation for others.

The experimental nature of the feature also means that the specification may change before reaching full standardization. Working Draft status indicates that the CSS Working Group is still refining the specification based on implementation experience and feedback. Developers should monitor browser updates and specification changes.

Feature Detection

Use CSS @supports to detect whether ::scroll-marker is available and provide appropriate styles. The selector() function tests whether a selector is supported, allowing you to check for scroll marker support independently from other CSS features.

@supports selector(::scroll-marker) {
 /* Scroll markers supported - use them */
 .scroll-container {
 scroll-marker-group: after;
 }
}

@supports not selector(::scroll-marker) {
 /* Fallback navigation for unsupported browsers */
 .scroll-container {
 /* Traditional navigation controls */
 }
}

Feature detection can apply to specific aspects of the implementation. You might enable scroll marker styling only when the feature is supported, while keeping fallback navigation visible for unsupported browsers. This approach aligns with modern web development best practices for progressive enhancement.

Progressive Enhancement Strategy

A robust implementation uses scroll markers as an enhancement rather than a requirement. Start with a scroll container that works with native scrolling and traditional navigation controls. Then, add scroll markers for browsers that support them, potentially hiding or enhancing the traditional controls.

For carousels, this might mean keeping visible previous/next buttons for all browsers but adding scroll marker indicators only where supported. For tabs, you might provide a select-based fallback for browsers without scroll marker support. The key is designing the interface so that removing scroll markers doesn't break functionality.

This approach ensures all users can navigate the interface regardless of their browser while providing an improved experience where possible. When combined with AI-powered development workflows, teams can automatically generate both fallback and enhanced implementations for different browser capabilities.

Frequently Asked Questions

Build Modern, Accessible User Interfaces

Our team specializes in creating user interfaces that leverage modern CSS capabilities while ensuring cross-browser compatibility and accessibility. From responsive carousels to accessible tab systems, we build interfaces that work for everyone.

Sources

  1. MDN Web Docs - ::scroll-marker - Official documentation covering syntax, description, and examples
  2. CSS-Tricks Almanac - ::scroll-marker - Comprehensive guide with practical examples and carousel implementations
  3. MDN Web Docs - scroll-marker-group property - Related property documentation
  4. CSSPortal - ::scroll-marker - Reference page with browser support information
::scroll-marker | CSS Pseudo-Element Guide | Digital Thrive US