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)

  1. Speculation
    1. Mobile moderate eagerness
    2. Target hint field
    3. Service worker prefetch
  2. HTTP
    1. Sec-Purpose: prefetch
    2. Clear-Site-Data new tokens
    3. Cache sharing for pervasive resources
  3. AI
    1. Summarizer
    2. Translator
    3. 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

  1. The content property accepts visible / "alt text". Before v138 the alt half only accepted strings.
  2. Now counter() and counters() work in the alt slot. The visible side and the accessible name can both reflect the live counter value.
  3. Critical for generated content like ::scroll-marker, ::marker, ::before, ::after — anywhere AT used to hear a glyph name with no context.
  4. "Tab 3" becomes "Chapter 3, Cache Sharing". "01.02" becomes "Section 1, subsection 2". The visual stays compact; the AT label gets full English.

see also