demo · v140

Scroll Marker Labels

The chromestatus motivation calls out ::scroll-marker: without alt text, a screen reader hears "Tab 8." With content: counter(chapter) / "Chapter " counter(chapter), it hears "Chapter 8." Same visual, dramatically different accessibility.

render mode:
  1. Introduction
  2. The story so far
  3. Setting up the problem
  4. A new approach
  5. Implementation
  6. Performance
  7. Migration tips
  8. What's next

screen reader output for the visual marker "8."

legacy: "Tab 8"

Chrome 140: "Chapter 8"

/* without alt text — screen reader announces just "8" */
li::before { content: counter(chapter) "."; }

/* with alt text (Chrome 140) — screen reader announces "Chapter 8" */
li::before { content: counter(chapter) "." / "Chapter " counter(chapter); }

/* counters() works the same — multilevel "Section 1.2.3" */
li::before {
  content: counters(section, ".") " "
           / counters(section, ".", "Section ");
}

The slash in the content property separates the rendered string from the alternative text used by the accessibility tree. Before Chrome 140 only literal strings were allowed on the alt side — the counter values couldn't be passed through, so generated numbering lost its semantics for screen reader users.

see also