::scroll-marker-group
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The ::scroll-marker-group
CSS pseudo-element is a container generated inside a scroll container, which contains any ::scroll-marker
pseudo-elements generated on the descendants of the scroll container.
Syntax
::scroll-marker-group {
/* ... */
}
Description
A scroll container's ::scroll-marker-group
pseudo-element automatically contains any ::scroll-marker
pseudo-elements generated on its descendants. This allows them to be positioned and laid out as a group, and is typically used when creating a CSS carousel, to create a scroll position indicator. The individual scroll markers can also be used to navigate to their associated content items.
The scroll-marker-group
property must be set to a non-none
value on the scroll container for a ::scroll-marker-group
pseudo-element to be generated; the chosen value determines where the scroll marker group appears in the carousel's tab order and layout box order (but not DOM structure) — before
puts it at the start, while after
puts it at the end.
It is a best practice to match the visual rendering position of the scroll marker group with the tab order. When placing the group at the start of the content, put it at the beginning of the tab order using before
. When placing the group at the end of the content, put it at the end of the tab order using after
.
Accessibility-wise, the scroll marker group and contained scroll markers are rendered with tablist
/tab
semantics. When you Tab to the group, it behaves like a single item (that is, another press of the Tab key will move past the group to the next item), and you can move between the different scroll markers using the left and right (or up and down) cursor keys.
Examples
Note: You can find a full example walkthough featuring the below code snippets in our Creating CSS carousels guide.
Generating and positioning a scroll marker group
In the below snippet, a scrolling <ul>
element's scroll-marker-group
property is set to after
, so the ::scroll-marker-group
pseudo-element is generated after the list's DOM content:
ul {
scroll-marker-group: after;
}
Next, the list's ::scroll-marker-group
pseudo-element is positioned relative to the container using CSS anchor positioning. First of all, a reference anchor-name
is set on the list. Next, each scroll button has its position
set to absolute
, and its position-anchor
property set to the same reference name defined on the list, to associate the two together. To position the group, we set a value on its top
property that uses an anchor()
function to position its top edge relative to the container's bottom edge, and horizontally center it on the container using a justify-self
value of anchor-center
.
The group is laid out using flexbox, with a justify-content
value of of center
and a gap
of 20px
so that its children (the ::scroll-marker
pseudo-elements) are centered inside the ::scroll-marker-group
with a gap between each one.
ul {
anchor-name: --myCarousel;
}
/* ... */
ul::scroll-marker-group {
position: absolute;
position-anchor: --myCarousel;
top: calc(anchor(bottom) - 70px);
justify-self: anchor-center;
display: flex;
justify-content: center;
gap: 20px;
}
Styling the scroll markers
The ::scroll-marker
pseudo-elements representing the scroll markers are generated on the <li>
chidren of the scrolling list, but are automatically placed inside the ::scroll-marker-group
pseudo-element.
The look of each one is handled by setting width
, height
, background-color
, border
, and border-radius
, but we also need to set a non-none
value for the content
property so they are actually generated. We also set an interactive
value of auto
so that all the markers will be interactive (by default, they are set to inert, and only the one corresponding to the currently visible "page" is interactive).
li::scroll-marker {
width: 16px;
height: 16px;
background-color: transparent;
border: 2px solid black;
border-radius: 50%;
content: "";
interactivity: auto;
}
Next, the :target-current
pseudo-class is used to select whichever scroll marker corresponds to the currently visible "page", highlighting how far the user has scrolled through the content. In this case, we set the background-color
to black
so it is styled as a filled-in circle.
li::scroll-marker:target-current {
background-color: black;
}
Specifications
Specification |
---|
CSS Overflow Module Level 5 # scroll-marker-group-pseudo |
Browser compatibility
See also
scroll-marker-group
andinteractivity
properties::scroll-button()
,::scroll-marker
, and::column
pseudo-elements:target-current
pseudo-class- Creating CSS carousels
- CSS overflow module
- CSS Carousel Gallery on chrome.dev (2025)