demo · v138
Scroll-marker carousel
The motivating use case from the explainer, made interactive. A carousel where each slide's ::scroll-marker displays the chapter number visually, but uses the alt-text slot of content to expose a full screen-reader-friendly label — "Chapter 3, Cache Sharing" instead of "tab 3".
Unflagged in Chrome 138.
counter() and counters() are now valid inside the alt text half of content: image / "alt text". This lets the visible glyph and the accessible name diverge — exactly what generated pseudo-elements need.
probing counter() in alt…
1 — Carousel ::scroll-marker
visible marker: 1 accessible name read by AT: "Chapter 1, Speculation Rules"
CSS: ::scroll-marker { content: counter(chapter) / "Chapter " counter(chapter) ", " attr(data-title); }
2 — Nested outline (counters() in alt)
- Speculation
- Mobile moderate eagerness
- Target hint field
- Service worker prefetch
- HTTP
- Sec-Purpose: prefetch
- Clear-Site-Data new tokens
- Cache sharing for pervasive resources
- AI
- Summarizer
- Translator
- Language Detector
visible: 02.01 AT: "Section 2, subsection 1". Same value, two surfaces.
The CSS
.slide {
counter-increment: chapter;
}
.slide::scroll-marker {
/* visual / alt — they can diverge */
content: counter(chapter)
/
"Chapter " counter(chapter) ", " attr(data-title);
}
.outline li::before {
/* counters() walks every nesting level */
content:
counter(section, decimal-leading-zero) "." counter(sub, decimal-leading-zero)
/
"Section " counter(section) ", subsection " counter(sub);
}
What's happening
- The
contentproperty acceptsvisible / "alt text". Before v138 the alt half only accepted strings. - Now
counter()andcounters()work in the alt slot. The visible side and the accessible name can both reflect the live counter value. - Critical for generated content like
::scroll-marker,::marker,::before,::after— anywhere AT used to hear a glyph name with no context. - "Tab 3" becomes "Chapter 3, Cache Sharing". "01.02" becomes "Section 1, subsection 2". The visual stays compact; the AT label gets full English.