diff --git a/source b/source index cd0d47cc723..c0889de352f 100644 --- a/source +++ b/source @@ -4390,7 +4390,18 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

In addition, the following aria-* content @@ -12910,6 +12921,8 @@ interface HTMLUnknownElement : HTMLElement { [CEReactions, Reflect] attribute boolean autofocus; [CEReactions, ReflectSetter] attribute long tabIndex; + [CEReactions, Reflect] attribute DOMString focusGroup; + [CEReactions, Reflect] attribute boolean focusGroupStart; undefined focus(optional FocusOptions options = {}); undefined blur(); }; @@ -14181,6 +14194,8 @@ https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C%21DOCTYPE%20HTML%3E%

  • dir
  • draggable
  • enterkeyhint
  • +
  • focusgroup
  • +
  • focusgroupstart
  • headingoffset
  • headingreset
  • hidden
  • @@ -85348,14 +85363,36 @@ dictionary CommandEventInit : EventInit { follows:

    @@ -85954,6 +85991,14 @@ dictionary CommandEventInit : EventInit { (For example, some platforms select the contents of a text control when that control is focused.)

    +
  • +

    If new focus target is a focus group item, + and the focus group owner does not have the nomemory token, then set new focus + target as the last focused item of the focus group owner.

    +
  • +
  • For each entry entry in new chain, in reverse order, run these substeps:

    @@ -86737,6 +86782,957 @@ dictionary CommandEventInit : EventInit {
    <div contenteditable autofocus>Edit <strong>me!</strong><div>
    +

    The focusgroupstart attribute

    + +
    +
    element . focusGroupStart
    +

    Reflects the focusgroupstart content + attribute.

    +
    + +

    The focusgroupstart content attribute + is a boolean attribute that can be set on individual focus group + items to control which element receives focus when entering a focus group segment via sequential focus navigation.

    + +

    When this attribute is present on a focus group + item and the user has not previously focused an item within that focus group segment (or if the nomemory token is specified), that item will be + the entry element for the + segment.

    + +

    The focusgroup attribute

    + +

    The focusgroup + content attribute provides declarative focus navigation for a group of related focusable + elements. When applied to an element, it enables Directional Navigation among its + focusable descendants, forming a focus group. Directional Navigation is + navigation by spatial direction (such as up, down, left, or right), as determined by the user + agent and input device (for example, arrow keys, gamepad, remote control, etc.). In contrast, + Sequential focus navigation refers to navigation in the order defined by the sequential focus navigation order (see definition), often via Tab and + Shift+Tab.

    + +
    +
    element . focusGroup
    +

    Reflects the focusgroup content attribute.

    +
    + +
    Concepts
    + +

    The attribute's value is a set of space-separated tokens. The first token must + either be a + behavior token, which defines the primary interaction pattern, or the special token + none which is used alone to opt out of focusgroup + behavior. If a behavior token is specified, then modifier tokens can be provided + subsequently.

    + +

    Token matching is ASCII case-insensitive.

    + +

    If the attribute value is the empty string, contains no recognized behavior + token as its first token, or the first token is a modifier token rather than a behavior token, then the element + is not a focus group owner and the attribute has no effect. If multiple + behavior tokens appear, then only the first is used. If + none appears alongside any other token, then the + entire attribute value is invalid and the element is neither a focus group + owner nor opted out of an ancestor focusgroup.

    + +

    Behavior tokens define the interaction pattern, + which refers to how the directional navigation inputs are used to move focus between focus group items.

    + +

    The following interaction patterns are defined:

    + + + + + + + + + + + + + + + + + + + +
    Token + Type + Interaction + Default modifiers + Description +
    toolbar + Behavior + Linear + inline + Indicates a toolbar pattern. Infers a toolbar role. +
    tablist + Behavior + Linear + inline + wrap + Indicates a tablist pattern. Infers a tablist role for the owner and a + tab role for items. +
    radiogroup + Behavior + Linear + wrap + Indicates a radiogroup pattern. Infers a radiogroup role for the + owner and a radio role + for items. +
    listbox + Behavior + Linear + block + Indicates a listbox pattern. Infers a listbox role for the owner + and an option role + for items. +
    menu + Behavior + Linear + block + wrap + Indicates a menu pattern. Infers a menu role for the owner and a + menuitem role for + items. +
    menubar + Behavior + Linear + inline + wrap + Indicates a menubar pattern. Infers a menubar role for the owner + and a menuitem role + for items. +
    wrap + Modifier + + + Enables navigation to wrap from the last item to the first, and vice-versa. +
    nowrap + Modifier + + + Explicitly disables wrapping. Useful for overriding a + behavior token's default wrap modifier. Cannot be + combined with wrap. +
    inline + Modifier + + + Restricts arrow key navigation to the inline axis (e.g., left/right arrows). +
    block + Modifier + + + Restricts arrow key navigation to the block axis (e.g., up/down arrows). +
    nomemory + Modifier + + + Disables the "last focused item" memory when re-entering the focus group. +
    none + Special + + + Opts the element and its descendants out of any ancestor focus group. Cannot be + combined with other tokens. +
    + +

    Certain behavior tokens carry default + modifiers that are automatically applied when the author does not explicitly specify a + conflicting modifier. Default modifiers align with ARIA Authoring Practices Guide (APG) conventions so + that common patterns require minimal configuration.

    + + + +

    The effective modifiers of a focus group owner are determined + by starting with the behavior token's default modifiers, then + applying any explicit modifier tokens from the + attribute value. For axis modifiers, an explicit inline or block token overrides any default axis restriction. + For wrap modifiers, an explicit nowrap + overrides a default wrap. If both wrap and nowrap are specified explicitly, then neither is + applied. If both inline and block are specified explicitly, then neither axis + restriction is applied.

    + +

    A focus group owner is an element with a valid focusgroup attribute specified, where the attribute value's + first token (when split on ASCII whitespace) is a behavior token (not none).

    + +

    The focus group scope of a focus group owner is all of its shadow-including descendants, excluding those + that are themselves a focus group owner, are in a different focus group scope, have opted out with focusgroup="none", are in the document's top + layer, or are shadow-including + descendants of an element that is both in the document's top layer + and is itself a shadow-including + descendant of the focus group owner.

    + +

    The focus group owner of an element is the + nearest shadow-including + ancestor that is a focus group owner and whose focus group + scope includes that element.

    + +

    A focus group segment is a contiguous group of focus group items within a focus group scope + that can be navigated without crossing any segment boundary. The following create segment + boundaries: sequentially focusable elements that have been opted out with focusgroup="none", nested focus group scopes that contain at least one focus group item, and + subtrees rooted at sequentially focusable elements in the document's top + layer that are shadow-including + descendants of the focus group owner.

    + +
    + +

    The following example illustrates how focus group segments are formed:

    + +
    <div focusgroup="toolbar">
    +  <button tabindex="0">A</button>        <!-- Segment 1 -->
    +  <button tabindex="0">B</button>        <!-- Segment 1 -->
    +  <span focusgroup="none">
    +    <button tabindex="0">C</button>      <!-- Not in focusgroup (opted out) -->
    +  </span>
    +  <button tabindex="0">D</button>  <!-- Segment 2 (new segment after opt-out) -->
    +  <button tabindex="0">E</button>        <!-- Segment 2 -->
    +</div>
    + +

    In this example, buttons A and B form the first segment, while + buttons D and E form a second segment. The opted-out span containing button C creates a + boundary between the segments.

    + +

    Each segment operates independently for:

    + + + +

    Arrow key navigation can move freely across segments, skipping over the opted-out + element C, but sequential focus navigation (Tab/Shift+Tab) + will treat these as two separate tab stops.

    + +
    + +

    A focus group item is an element that is a focusable area + within a focus group scope and whose tabindex + value is not a negative integer.

    + +

    Each focus group owner has a last focused item, which is either null + or a focus group item that was most recently focused within its focus group + scope. It is initially null.

    + +

    Elements with tabindex="-1" within a + focus group scope are not focus group items + and are not reachable via Directional Navigation. However, if such an element + becomes focused through other means (e.g., programmatically or via mouse click), the user can + navigate away from it using arrow keys to reach focus group + items.

    + +

    The order-modified document order is the + ordering of elements used for sequential focus navigation after applying any layout reordering + semantics that affect keyboard navigation order, such as the CSS order + property for flex items and grid items, or the CSS reading-flow + property. If no such reordering applies to a set of elements, then their order-modified document order is identical to + shadow-including tree order.

    + +

    Both sequential focus navigation + (Tab/Shift+Tab) and Directional Navigation (arrow keys) + follow order-modified document order. When the CSS reading-flow property is applied to a focusgroup's container, arrow key + presses move focus in the expected visual direction established by the reading flow, and the + direction of an arrow key is determined by the visual position of items in that order.

    + +
    Top layer interaction
    + +

    Elements in the document's top layer — such as popovers shown via showPopover(), modal dialog elements, + and fullscreen elements — are excluded from any ancestor focus group scope while + they remain in the top layer. This exclusion has the same effect as focusgroup="none" for the purpose of ancestor focusgroup + participation: the element and its shadow-including + descendants do not appear as focus group items in + the ancestor's scope, Directional Navigation in the ancestor focusgroup skips the + excluded subtree, and the subtree creates a segment + boundary for sequential focus navigation.

    + +

    When an element leaves the top layer (for example, after a popover is fully + removed from the top layer), + the element and its descendants participate in the ancestor focus group scope again + under the normal rules.

    + +

    If the ancestor focusgroup's last focused item is within a subtree rooted at + an element that enters the top layer, then the last focused item is + ineligible for memory restoration.

    + +

    A focusgroup attribute on the top-layer element itself + continues to operate normally. Only participation in ancestor focusgroups changes.

    + +
    + +

    In this example, a toolbar contains a popover. When the popover is hidden, arrow keys in + the toolbar move among the four buttons. When the popover is shown and enters the top + layer, its subtree is excluded from the toolbar's focus group scope:

    + +
    <div focusgroup="toolbar wrap" aria-label="Text formatting">
    +  <button tabindex="0" type="button" aria-haspopup="true" aria-expanded="false"
    +          aria-controls="color-picker" commandfor="color-picker"
    +          command="show-popover">Text color</button>
    +  <button tabindex="0" type="button">Bold</button>
    +  <button tabindex="0" type="button">Italic</button>
    +  <div id="color-picker" popover>
    +    <button tabindex="0" type="button">Red</button>
    +    <button tabindex="0" type="button">Green</button>
    +    <button tabindex="0" type="button">Blue</button>
    +  </div>
    +  <button tabindex="0" type="button">Underline</button>
    +</div>
    + +

    Arrow keys in the toolbar skip the popover's buttons. The popover's content remains + reachable via sequential focus navigation when it is shown. The excluded subtree + also creates a segment boundary within the + toolbar.

    + +
    + +
    + +

    If the popover defines its own focusgroup, that inner + focusgroup operates independently:

    + +
    <div focusgroup="toolbar wrap" aria-label="Text formatting">
    +  <button tabindex="0" type="button" aria-haspopup="true" aria-expanded="false"
    +          aria-controls="color-picker" commandfor="color-picker"
    +          command="show-popover">Text color</button>
    +  <button tabindex="0" type="button">Bold</button>
    +  <div id="color-picker" popover focusgroup="radiogroup"
    +       aria-label="Color palette">
    +    <button tabindex="0" type="button" role="radio" aria-checked="true">Red</button>
    +    <button tabindex="0" type="button" role="radio" aria-checked="false">Green</button>
    +    <button tabindex="0" type="button" role="radio" aria-checked="false">Blue</button>
    +  </div>
    +  <button tabindex="0" type="button">Underline</button>
    +</div>
    + +

    The popover's subtree is excluded from the parent toolbar's focusgroup when shown. Once + focus moves into the popover, its own radiogroup focusgroup provides independent arrow + key navigation among the color choices.

    + +
    + +
    ARIA Role Inference
    + +

    When a behavior token is used, the user agent may + infer a corresponding ARIA role for the focus group + owner and its items. The user agent must + not infer a container role unless the element would otherwise have a generic role (such + as a div or span), does not have an explicit role attribute, and does not have non-generic native + semantics (such as nav, ul, or table).

    + +

    Child role inference additionally applies to button elements that lack an explicit + role attribute, because buttons are the most common building + block for composite widget items (tabs, menu items, radio-like toggles, etc.). Other native + interactive elements (links, inputs, etc.) retain their native semantics and are never overwritten + by inference.

    + +

    For example, <div focusgroup="toolbar"> would be exposed with a toolbar role. However, if the element has existing + semantics (such as <nav focusgroup="toolbar">) or an explicit role + (such as <div focusgroup="toolbar" role="navigation">), the existing + role is preserved and only the focus navigation behavior is applied.

    + +

    When native semantics are preserved (such as on a nav element), + the exposed role may not cause assistive technologies to switch to a mode + where arrow keys are passed to the page. Authors who need composite widget keyboard behavior + should ensure the exposed role is a composite widget role (such as + toolbar), either through inference or by + setting an explicit role attribute.

    + +

    Role inference never overrides explicit author-defined roles or meaningful + native-element semantics. It also does not infer variant roles like menuitemcheckbox; authors + specify such roles explicitly.

    + +

    The focusgroup attribute does not + automatically infer or set aria-orientation from + inline or block tokens. The inline and block tokens control keyboard behavior (which + arrow keys are active), while aria-orientation conveys + semantic structure to assistive technologies. Authors can set aria-orientation explicitly when the default does not match + the widget's semantic structure.

    + +
    +

    When an axis modifier conflicts with the inferred role's default + aria-orientation, authors must set an explicit + aria-orientation attribute:

    + +
    <!-- toolbar: horizontal default, block restricts to vertical -->
    +<div focusgroup="toolbar block" aria-orientation="vertical">
    +  <button tabindex="0">Cut</button>
    +  <button tabindex="0">Copy</button>
    +  <button tabindex="0">Paste</button>
    +</div>
    +
    + +
    Focus Handling
    + +
    Event Handling
    + +

    Directional Navigation is triggered as the default action of a keydown event for an arrow key when focus is on a focus group item. User agents may also handle + Home and End keys to move focus to the first or last item in the + focus group scope.

    + +

    If a keydown event's canceled flag is set + (for example, because an event listener called preventDefault()), then the user agent must not + perform Directional Navigation. keyup + events do not trigger Directional Navigation.

    + +

    When any modifier key is held (Ctrl, Alt, Meta, or + Shift), the user agent must not trigger Directional + Navigation, allowing modifier+arrow combinations to retain their + platform-specific behaviors (such as word-by-word text navigation with + Ctrl+Arrow, or text selection with + Shift+Arrow).

    + +

    Authors who need to handle arrow keys for custom behavior can call preventDefault() on the keydown event to prevent Directional Navigation from + occurring.

    + +
    Directional Navigation
    + +
    +

    When the user presses a directional input key (such as an arrow key) without any + modifier keys held, and the currently focused area of a top-level traversable's + DOM anchor is a focusable area within a focus group + scope, the user agent must run these steps as the default action of the + keydown event:

    + +
      +
    1. If the keydown event's canceled + flag is set, then return.

    2. + +
    3. Let currentItem be the currently focused area of a top-level + traversable's DOM anchor.

    4. + +
    5. If currentItem is a key conflict element whose native + arrow key behavior uses the same axis (inline or block) as the pressed key, then + return.

    6. + +
    7. Let owner be the focus group + owner of currentItem.

    8. + +
    9. If owner is null, then return.

    10. + +
    11. If the pressed key's axis (inline or block, as determined by owner's + computed writing mode and directionality) is not + among owner's effective inline or block modifiers (including any default + modifiers from the behavior token), then return.

    12. + +
    13. Let direction be forward if the pressed key points toward the + inline-end or block-end direction (based on the focus group owner's + writing mode and directionality), or backward if it points toward the inline-start + or block-start direction.

    14. + +
    15. Let items be all focus group items in + owner's focus group scope, in order-modified document + order.

    16. + +
    17. If items is empty, then return.

    18. + +
    19. If direction is forward, then let nextItem be the first + element in items that follows currentItem in order-modified + document order, or null if no such element exists. Otherwise, let + nextItem be the last element in items that precedes + currentItem in order-modified document order, or null if no + such element exists.

    20. + +
    21. If nextItem is null and owner's effective modifiers + include wrap (either explicitly or via + default modifiers, and not overridden by nowrap), then set nextItem to the + last element in items if direction is backward, or the first + element in items if direction is forward.

    22. + +
    23. If nextItem is not null and nextItem is + connected, then run the focusing steps for + nextItem.

    24. +
    +
    + +

    When the user presses Home or End without any modifier keys + held, and the currently focused area of a top-level traversable's DOM + anchor is a focus group item, the user agent + may move focus to the first or last focus group item + in the focus group scope (in order-modified document order), + respectively, as the default action of the keydown + event. As with Directional Navigation, the user agent must not perform + this behavior if the event's canceled flag is set.

    + +
    Determining the entry element for sequential + focus navigation
    + +
    +

    The entry element of a focus group segment given a focus group segment segment is as follows:

    + +
      +
    1. Let owner be the focus group + owner of any focus group item in segment.

    2. + +
    3. If owner has a last focused item, owner does not have + the nomemory token, the last focused item is within segment, and the + last focused item is not in the document's + top layer and does not have a shadow-including ancestor that is both in the + document's top layer and is a shadow-including descendant of owner, then return the last focused item.

    4. + +
    5. If any focus group item in segment has the focusgroupstart attribute, then return the first + such element in order-modified document order.

    6. + +
    7. If any focus group item in segment is sequentially + focusable, then return the first such element in order-modified document + order.

    8. + +
    9. Return the first focus group item in segment in + order-modified document order.

    10. +
    +
    + +

    All focus group items in a focus + group segment share the same focus group owner.

    + +

    The user agent must clear the last focused item of a focus group + owner whenever any of the following occurs:

    + + + +
    +

    This example shows how opted-out elements create multiple focusgroup entry points:

    + +
    <div focusgroup="toolbar wrap" aria-label="Text formatting">
    +  <button tabindex="0" type="button">Bold</button>
    +  <button tabindex="0" type="button">Italic</button>
    +  <span focusgroup="none" aria-label="Help group">
    +    <button tabindex="0" type="button">Help</button>
    +    <button tabindex="0" type="button">Shortcuts</button>
    +  </span>
    +  <button tabindex="0" type="button">Underline</button>
    +</div>
    + +

    Sequential focus navigation behavior:

    +
      +
    1. Entering from before the focusgroup: Pressing + Tab focuses "Bold" (first focus group item).

    2. + +
    3. Tab from "Bold": Focuses "Help" (opted-out elements remain + in sequential navigation order).

    4. + +
    5. Tab from "Help": Focuses "Shortcuts" (normal sequential + navigation within opted-out subtree).

    6. + +
    7. Tab from "Shortcuts": Enters the second focus group + segment, focusing "Underline".

    8. + +
    9. Shift+Tab from "Help": Moves focus back to the focusgroup + segment before "Help", focus will be set on "Bold".

    10. +
    + +

    Arrow key navigation is unaffected by opted-out elements: pressing the right + arrow on "Italic" moves focus directly to "Underline", treating the opted-out span as if it + doesn't exist for directional navigation purposes.

    +
    + +
    +

    This example shows a tablist with manual activation and disabled + memory. Because tablist carries inline and wrap as default modifiers, only nomemory needs to be specified explicitly:

    + +
    <div focusgroup="tablist nomemory"
    +     aria-label="Common Operating Systems">
    +  <button tabindex="0" id="tab-1" aria-selected="false"
    +          aria-controls="tabpanel-1">macOS</button>
    +  <button tabindex="0" id="tab-2" aria-selected="true"
    +          aria-controls="tabpanel-2"
    +          focusgroupstart>Windows</button>
    +  <button tabindex="0" id="tab-3" aria-selected="false"
    +          aria-controls="tabpanel-3">Linux</button>
    +</div>
    +<div id="tabpanel-1" role="tabpanel" tabindex="0"
    +     aria-labelledby="tab-1" hidden> … </div>
    +<div id="tabpanel-2" role="tabpanel" tabindex="0"
    +     aria-labelledby="tab-2"> … </div>
    +<div id="tabpanel-3" role="tabpanel" tabindex="0"
    +     aria-labelledby="tab-3" hidden> … </div>
    + +

    What to notice:

    + +
    + +
    +

    This example shows a toolbar where the focusgroupstart attribute designates a + preferred entry point:

    + +
    <div focusgroup="toolbar" aria-label="Text formatting">
    +  <button tabindex="0" type="button">Undo</button>
    +  <button tabindex="0" type="button">Redo</button>
    +  <button tabindex="0" type="button" focusgroupstart>Bold</button>
    +  <button tabindex="0" type="button">Italic</button>
    +  <button tabindex="0" type="button">Underline</button>
    +</div>
    + +

    Sequential focus navigation behavior:

    +
      +
    1. Entering from before: Pressing Tab focuses "Bold" + (has focusgroupstart, taking precedence + over order-modified document + order).

    2. + +
    3. After arrow navigation to "Italic": Pressing Tab + to leave and then Shift+Tab to return focuses "Italic" (memory of last + focused item takes precedence over focusgroupstart).

    4. +
    +
    + +
    Key Conflict Elements
    + +

    A key conflict element is a focus group + item that has native (built-in) arrow key behavior that conflicts with + Directional Navigation. Which elements are considered key conflict + elements, and on which axes, is determined by the user agent based on the element's + built-in arrow key behavior.

    + +
    +

    Examples of elements that are typically key conflict elements include:

    + + +
    + +

    Key conflict elements can be reached via + Directional + Navigation. However, once a key conflict element has focus, its + native arrow key behavior takes precedence and Directional Navigation does + not occur (the algorithm returns at step 3).

    + +

    To allow users to escape a key conflict element via + sequential focus navigation, the tabindex-ordered focus navigation + scope is modified when the currently focused area of a top-level + traversable's DOM anchor is a key conflict element: all + focus group items in the same focus group + scope are treated as entry elements, so that forward sequential navigation moves focus to + the next focus group item in order-modified document + order, and backward sequential navigation moves focus to the previous + one. If no adjacent focus group item exists in the navigation direction, + sequential navigation proceeds normally beyond the focusgroup.

    + +

    On most desktop platforms, sequential focus navigation is + triggered by Tab (forward) and Shift+Tab (backward). On other + platforms (such as TV remotes or game controllers), the user agent determines the + appropriate input for sequential navigation.

    + +

    This override applies only when the DOM anchor of the currently + focused area of a top-level traversable is the key conflict element + itself. When focus is on a focusable area whose + DOM anchor is a descendant of the key conflict element (such as + a control within a video element's user-agent shadow tree), the override does + not apply, and normal sequential focus navigation applies within the + element's internal controls.

    + +

    Key conflict elements are + determined by the user agent based on native element behavior. Elements where authors + have added scripted arrow key handlers (e.g., via keydown event listeners that call preventDefault()) are not automatically + treated as key conflict elements. Authors who add such handlers can manage conflicts + by using focusgroup="none" to opt the + element out, by limiting the focusgroup's axis via inline or block to avoid the conflicting axis, or by + implementing an activation step to enter the element and an escape step (such as + Escape) to leave it.

    + +
    +

    In this toolbar example, the search input is a key conflict element:

    + +
    <div focusgroup="toolbar" aria-label="Text formatting">
    +  <button tabindex="0" type="button">Bold</button>
    +  <button tabindex="0" type="button">Italic</button>
    +  <input type="text" placeholder="Search" /> <!-- Key conflict element -->
    +  <button tabindex="0">Go</button>
    +  <button tabindex="0" type="button">Save</button>
    +  <button tabindex="0" type="button">Print</button>
    +</div>
    + +

    Because the search input is a key conflict element, + Tab/Shift+Tab while it has focus moves to the adjacent + focus group item:

    + +
    + +
    Scrolling Interactions
    + +

    Focusgroup navigation coexists with scrolling behavior. Arrow keys are commonly used + for both focus navigation and scrolling; the priority and interaction between these + behaviors depends on the context.

    + +

    When a focusgroup is contained within a scrollable region:

    + + +

    Since Directional Navigation takes priority over scrolling, take care + when constructing large focusgroups to avoid situations where content could be missed when jumping + from one item to another.

    + +

    When a scrollable element is contained within a focusgroup, the behavior depends on + whether the scrollable element is focusable (which may vary between user agents) and + whether there is a conflict between the focusgroup's arrow key handling and the + scrollable element's needs:

    + + +
    +

    This example shows a focusgroup with restricted axis containing a scrollable region:

    + +
    <div style="height: 200px; overflow: auto;">
    +  <div focusgroup="listbox block">
    +    <div tabindex="0" aria-selected="true">Item 1</div>
    +    <div tabindex="0" aria-selected="false">Item 2</div>
    +    <div tabindex="0" aria-selected="false">Item 3</div>
    +    <!-- Items 4-97 would be here, creating a long scrollable list -->
    +    <div tabindex="0" aria-selected="false">Item 98</div>
    +    <div tabindex="0" aria-selected="false">Item 99</div>
    +    <div tabindex="0" aria-selected="false">Item 100</div>
    +  </div>
    +</div>
    + +

    In this example:

    + +
    + +
    +

    This example shows nested focusgroups in a menubar/menu pattern. Each focusgroup is + independent, and default modifiers automatically configure the correct axis and + wrapping for each pattern:

    + +
    <ul focusgroup="menubar" aria-label="Mythical University">
    +  <li role="none">
    +    <a role="menuitem" popovertarget="aboutpop" href="…">About</a>
    +    <ul focusgroup="menu" autofocus id="aboutpop" aria-label="About" popover>
    +      <li role="none"><a role="menuitem" href="…">Overview</a></li>
    +      <li role="none"><a role="menuitem" href="…">Administration</a></li>
    +    </ul>
    +  </li>
    +  <li role="none">
    +    <a role="menuitem" popovertarget="admitpop" href="…">Admissions</a>
    +    <ul focusgroup="menu" autofocus id="admitpop" aria-label="Admissions" popover>
    +      <li role="none"><a role="menuitem" href="…">Apply</a></li>
    +      <li role="none"><a role="menuitem" href="…">Visit</a></li>
    +    </ul>
    +  </li>
    +</ul>
    + +

    What to notice:

    + +
    +

    Assigning keyboard shortcuts