Nested Focusgroups

A nested focusgroup creates an independent navigation scope within an outer focusgroup. Each group has its own axis, wrapping, memory, and entry point. Tab moves between groups; arrows navigate within.

focusgroup="toolbar inline" (outer) + focusgroup="toolbar inline wrap" (inner)
Try it: Use in the outer toolbar. When focus reaches the nested group, press Tab to enter it. Use arrows inside, then Tab to exit back to the outer toolbar.
View source
<div focusgroup="toolbar inline" aria-label="Main
     toolbar">
    <button type="button">Save</button>
    <button type="button" focusgroupstart>Print</button>
    <div focusgroup="toolbar inline wrap" aria-label="Text formatting">
        <button type="button">Bold</button>
        <button type="button">Italic</button>
        <button type="button">Underline</button>
    </div>
    <button type="button">Close</button>
    <button type="button">Exit</button>
</div>

Opt-Out Segments with focusgroup="none"

Use focusgroup="none" to exclude specific elements from arrow navigation while keeping them tabbable. Arrow keys skip right over them.

focusgroup="toolbar inline"
Try it: Use to navigate through the toolbar. Notice that "Help" and "Shortcuts" are skipped by arrow keys but still reachable via Tab.
View source
<div focusgroup="toolbar inline"
     aria-label="Segmented toolbar">
    <button type="button">New</button>
    <button type="button">Open</button>
    <button type="button">Save</button>
    <span focusgroup="none">
        <button type="button">Help</button>
        <button type="button">Shortcuts</button>
    </span>
    <button type="button">Close</button>
    <button type="button">Exit</button>
</div>

Deep Descendant Discovery

Focusgroup items don't need to be direct children. The browser discovers focusable descendants at any depth (unless they are inside a nested focusgroup or focusgroup="none").

focusgroup="toolbar inline"
Try it: Use — arrow navigation works even though buttons are deeply nested inside <div> and <span> wrappers.
View source
<div focusgroup="toolbar inline"
     aria-label="Nested wrappers">
    <div>
        <span><button
             type="button">Alpha</button></span>
        <span><button type="button">Beta</button></span>
        <span><button
             type="button">Gamma</button></span>
    </div>
</div>

CSS reading-flow Integration

When CSS changes the visual order (e.g., flex-direction: row-reverse), reading-flow: flex-visual tells the focusgroup to follow the visual order rather than the DOM source order.

focusgroup="toolbar" + reading-flow: flex-visual
Try it: Use to navigate. With reading-flow: flex-visual, arrow navigation follows the visual left-to-right order (C → B → A), not the DOM order (A → B → C).
View source
<div focusgroup="toolbar" aria-label="Visual
     order"
     style="display: flex; flex-direction: row-reverse;
            reading-flow: flex-visual;">
    <button type="button">A (DOM first)</button>
    <button type="button">B (DOM second)</button>
    <button type="button">C (DOM third)</button>
</div>

Feature Detection

Check whether the browser supports focusgroup before relying on it. If unsupported, you can fall back to a JavaScript-based roving tabindex or show a notice.

View source
<script>
if ('focusgroup' in HTMLElement.prototype) {
    // focusgroup is supported — use it!
    console.log('focusgroup is supported');
} else {
    // Not supported — fall back to JS roving tabindex
    console.log('focusgroup is NOT supported');
}
</script>