v154 · scroll-marker-group · migration
The ARIA tabs migration
On the left, the widget every design system carries: a WAI-ARIA tabs implementation with roving tabindex, an arrow-key handler, aria-selected bookkeeping and panel hiding — all of it script, all of it working, all of it yours to maintain. On the right, the same interface where scroll-marker-group: before tabs makes the browser responsible for every one of those jobs.
Same widget, two owners
Hand-rolled ARIA (works everywhere)
64 lines of markup + script on this page. Use arrow keys on the tabs.
Ticket #4021 — the browser knows nothing about these tabs; every behaviour below is scripted.
Three comments, one status change. This panel is hidden with the hidden attribute the script toggles.
Two attachments. Forget to move tabindex in the keydown handler and keyboard users lose the widget.
CSS tabs mode (Chrome 154)
Zero ARIA attributes, zero tab-switching script.
Ticket #4021 — the strip above is a ::scroll-marker-group; in tabs mode the browser assigns tablist/tab/tabpanel roles itself.
Three comments, one status change. No hidden toggling: inactive panels are pruned from the accessibility tree by the mode.
Two attachments. Roving focus is the focusgroup's job now, not a keydown handler's.
The CSS version, in full
.css-tabs {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-marker-group: before tabs;
}
.css-tabs > div { min-width: 100%; scroll-snap-align: center; }
.css-tabs > div::scroll-marker { content: attr(data-label); }
.css-tabs > div::scroll-marker:target-current { background: black; color: white; }
| job | hand-rolled ARIA version | tabs mode |
|---|---|---|
| roles | role="tablist" / "tab" / "tabpanel" on 7 elements | implicit from the mode |
| selection state | aria-selected toggled in script | :target-current |
| roving tabindex | tabindex="-1" juggling in a keydown handler | focusgroup behaviour of the mode |
| arrow keys | ArrowLeft/ArrowRight listener, wrap-around logic | built in |
| hiding inactive panels | hidden attribute toggled per switch | accessibility-tree pruning |
| focus into panel | tabindex="0" on each panel | marker is a focus-navigation-scope owner |