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
buttonlistboxmenumenubarmenuitemmenuitemcheckboxoptionpresentationradioradiogrouptabtablisttoolbarIn 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%
dirdraggableenterkeyhintfocusgroupfocusgroupstartheadingoffsetheadingresethiddenIt contains all elements in owner's focus navigation scope that - are themselves focus navigation scope owners, - except the elements whose tabindex value is a negative integer.
It contains all of the focusable areas whose - DOM anchor is an element in owner's focus navigation scope, - except the focusable areas whose tabindex value - is a negative integer.
It contains all elements in owner's focus navigation scope that + are themselves focus navigation scope owners, + except:
+It contains all of the focusable areas whose + DOM anchor is an element in owner's focus navigation + scope, except:
+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>
+ focusgroupstart attributefocusGroupStartReflects 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.
focusgroup attributeThe 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.
focusGroupReflects the focusgroup content attribute.
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:
+ +Linear: Enables sequential navigation
+ forwards and backwards through a set of focusable items. In a linear interaction pattern, even when both directional input axes are allowed
+ (such as when neither inline nor block modifiers are specified), navigation follows the
+ document order of the items rather than spatial positioning.
| 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.
+ +An explicit modifier always overrides the corresponding default. For example, focusgroup="tablist block" overrides the default inline with block.
The nowrap token explicitly disables
+ wrapping, overriding a behavior token's default wrap modifier. For example, focusgroup="tablist nowrap" produces a tablist that does not wrap.
Specifying both wrap and nowrap in the same attribute value is an error;
+ neither will be applied.
Specifying both inline and block in the same attribute value is an error;
+ neither axis restriction will be applied and both axes will be allowed (the
+ default).
Explicitly specifying the same modifier as the default is redundant but valid
+ (e.g., focusgroup="tablist inline wrap" is equivalent to focusgroup="tablist").
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:
+ +Guaranteed tab stop: Each segment ensures exactly one tab-accessible element.
Sequential navigation: Tab and Shift+Tab treat each segment as a + separate focusgroup entry point.
Entry element determination: The focusgroupstart attribute is evaluated per-segment, and
+ the focusgroup's last focused item is only used if it falls within the segment
+ being entered.
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.
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.
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>
+ 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.
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:
If the keydown event's canceled
+ flag is set, then return.
Let currentItem be the currently focused area of a top-level + traversable's DOM anchor.
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.
Let owner be the focus group + owner of currentItem.
If owner is null, then return.
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.
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.
Let items be all focus group items in + owner's focus group scope, in order-modified document + order.
If items is empty, then return.
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.
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.
If nextItem is not null and nextItem is + connected, then run the focusing steps for + nextItem.
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.
The entry element of a focus group segment given a focus group segment segment is as follows:
+ +Let owner be the focus group + owner of any focus group item in segment.
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.
If any focus group item in segment has the focusgroupstart attribute, then return the first
+ such element in order-modified document order.
If any focus group item in segment is sequentially + focusable, then return the first such element in order-modified document + order.
Return the first focus group item in segment in + order-modified document order.
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:
+ +The focus group owner or the last focused item has
+ its hidden attribute added.
The focus group owner or the last focused item has
+ its actually disabled or inert state changed.
The focus group owner or the last focused item is + removed from a + document.
The last focused item stops being a focusable area (for example, a div with a tabindex attribute has that attribute
+ removed).
The last focused item is no longer within the focus group
+ scope of its focus group owner (for example, because focusgroup="none" is added to it or a
+ shadow-including ancestor, or a new
+ focusgroup attribute is added to it or a
+ shadow-including ancestor), unless
+ the last focused item is no longer within the scope solely because it, or a
+ shadow-including ancestor, is in
+ the document's top layer (in which case the last focused item
+ is ineligible for memory restoration, as described in the top layer interaction
+ section).
The focus group owner's focusgroup attribute is removed or changed such that
+ the element is no longer a focus group owner.
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:
+Entering from before the focusgroup: Pressing + Tab focuses "Bold" (first focus group item).
Tab from "Bold": Focuses "Help" (opted-out elements remain + in sequential navigation order).
Tab from "Help": Focuses "Shortcuts" (normal sequential + navigation within opted-out subtree).
Tab from "Shortcuts": Enters the second focus group + segment, focusing "Underline".
Shift+Tab from "Help": Moves focus back to the focusgroup + segment before "Help", focus will be set on "Bold".
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:
+button elements receive the inferred tab role because button is eligible for child
+ role inference inside a tablist focusgroup.focusgroupstart attribute on the selected
+ tab determines which tab receives focus when entering the focusgroup. The nomemory value prevents the focusgroup from
+ remembering the last focused tab, so that focus will always go to the tab with focusgroupstart on re-entry.tablist carries wrap as a default modifier.tablist carries inline as a default modifier.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:
+Entering from before: Pressing Tab focuses "Bold"
+ (has focusgroupstart, taking precedence
+ over order-modified document
+ order).
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).
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:
+ +input elements (most, but not all types use arrow keys)textarea elementsselect elements when the arrow-key axis used by the
+ focusgroup is the same axis used by the select elementcontenteditable attributeaudio and video elements with visible controlsiframe and object elements with focusable content insideKey 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:
+Arrow keys are consumed for text cursor navigation.
Pressing Tab from the input moves focus to "Go" (the next + focus group item).
Pressing Shift+Tab from the input moves focus to "Italic" + (the previous focus group item).
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:
+For focusgroups with wrap behavior: Focus
+ navigation takes priority over scrolling. Arrow keys will move focus between focus group items, wrapping from end to start as configured.
+ Scrolling will only occur as needed to bring the focused element into view.
For focusgroups without wrap behavior: Focus
+ navigation takes priority until the focus reaches a boundary (first or last item). Once at a
+ boundary, continuing to press arrow keys in the same direction will allow normal scrolling
+ behavior to resume.
For focusgroups with axis restrictions: If a focusgroup limits arrow keys to a specific
+ axis (using inline or block tokens), then arrow keys in the cross-axis will be
+ available for scrolling.
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:
+No conflict scenarios: When the focusgroup is limited to one axis and the + scrollable element scrolls on the cross-axis, or when the scrollable element scrolls + via different keys (such as Page Up/Page Down), both behaviors + can coexist.
Conflict scenarios: When a focusable scrollable element and the focusgroup both + use arrow keys on the same axis, the scrollable element is treated as a key conflict element. Arrow keys are consumed by + the scrollable element for scrolling, and Tab/Shift+Tab can be + used to navigate to adjacent focus group + items.
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:
+block.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:
+menubar carries inline and wrap as default modifiers, so menuitems
+ respond to left/right arrow keys and wrap at the ends.menu carries block and wrap as default modifiers, so menuitems
+ respond to up/down arrow keys and wrap at the ends.menu creates a new focusgroup and implicitly opts out of
+ the ancestor menubar.popover
+ and autofocus attribute behaviors, not by
+ focusgroup.