You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Index of focusgroup values](#index-of-focusgroup-values)
75
67
-[Acknowledgments](#acknowledgments)
68
+
69
+
</details>
76
70
## Introduction
77
71
78
-
Authors routinely hand-code “roving tabindex” logic for composite widgets like toolbars, tablists, menus, listboxes and grids. In practice, this means providing a single tab stop (see [Sequential focus navigation](#keyboard-navigation-modes)) to enter the control, then using directional navigation (arrow keys / D-pad—see [Directional navigation](#keyboard-navigation-modes)) to move focus between items.
72
+
Authors routinely hand-code “roving tabindex” logic for composite widgets like toolbars, tablists, menus, listboxes and grids. In practice, this means providing a single tab stop to enter the control, then using directional navigation (arrow keys / D-pad) to move focus between items.
79
73
80
74
Authors may use the proposed `focusgroup` HTML attribute to declare that
81
75
a subtree of focusable elements will get:
82
-
1. Focus navigation ([not selection](#non-goals)) using keyboard directional arrow keys (D-pad style) for linear groups (see [Directional navigation](#keyboard-navigation-modes)).
Benefits over ad-hoc scripts (FocusZone, Tabster, bespoke roving tabindex): less boilerplate, standardized axis + wrap behavior (including RTL / vertical), reduced misapplication, and a consistent, testable baseline for AT and UA interoperability.
91
+
92
+
### Keyboard Navigation Modes
97
93
Two complementary navigation paradigms are often used on the web today:
98
94
99
-
### 1. Sequential focus navigation
95
+
####1. Sequential focus navigation
100
96
(Tab / Shift+Tab): The browser-managed order of tabbable elements (`tabindex` / native semantics). Used to enter or leave a composite.
101
-
### 2. Directional navigation
102
-
(Arrow keys, D-pad, some AT commands): Moves focus among a logically related set of items inside a composite without leaving it (the “[roving tabindex](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Guides/Keyboard-navigable_JavaScript_widgets#technique_1_roving_tabindex)” pattern when hand-authored).
103
-
104
-
`focusgroup` standardizes the directional layer for supported composite patterns and guarantees exactly one sequential entry point per [focusgroup segment](#focusgroup-segments)—without authors having to dynamically set and unset `tabindex` across items. Authors only ensure that intended items are focusable; `focusgroup` handles: (a) roving single tab stop per segment, (b) directional navigation (inline/block aware), (c) optional wrap, (d) memory (unless `no-memory`).
105
-
106
-
Key points:
107
-
* Tab / Shift+Tab enters or exits a focusgroup segment at one guaranteed entry point.
108
-
* Arrow keys / D-pad move internally among items.
109
-
* Multiple naturally tabbable descendants do NOT create multiple tab stops; focusgroup collapses them to one per segment.
110
-
* Authors do not need to force `tabindex="-1"` on every non-active item; it is optional.
111
-
112
-
See: [Guaranteed tab stop](#guaranteed-tab-stop) and the [Guaranteed tab stop algorithm](#guaranteed-tab-stop-algorithm).
113
-
114
-
115
-
Benefits over ad-hoc scripts (FocusZone, Tabster, bespoke roving tabindex): less boilerplate, standardized axis + wrap behavior (including RTL / vertical), reduced misapplication, and a consistent, testable baseline for AT and UA interoperability.
97
+
#### 2. Directional navigation
98
+
(Arrow keys, D-pad, some AT commands): Moves focus among a logically related set of items inside a composite without leaving it, the “[roving tabindex](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Guides/Keyboard-navigable_JavaScript_widgets#technique_1_roving_tabindex)” pattern when hand-authored.
116
99
117
100
### Before / After at a glance:
118
101
@@ -201,15 +184,15 @@ Minimum role application (container & children): User agents apply the minimum c
201
184
202
185
Current behavior tokens (APG alignment & minimum roles). All listed (except the future grid token) produce the same linear navigation semantics—only semantic expectations & child inference differ:
203
186
204
-
| Behavior | APG Pattern |MDN Role Docs |Minimum container role (when applied) | Minimum child role(s) (when applied) | APG Pattern Link |
|`radiogroup`| Radio Group |[MDN `role=radiogroup`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/radiogroup_role)|`radiogroup`|`radio`|[APG Radio Group](https://www.w3.org/WAI/ARIA/apg/patterns/radio/)|
|`menu`| Menu |[MDN `role=menu`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menu_role)|`menu`|`menuitem`|[APG Menu / Menubar](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)|
211
-
|`menubar`| Menubar |[MDN `role=menubar`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_role)|`menubar`|`menuitem`|[APG Menu / Menubar](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)|
|`radiogroup`| Radio Group |[`radiogroup`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/radiogroup_role)|[`radio`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/radio_role)|[APG Radio Group](https://www.w3.org/WAI/ARIA/apg/patterns/radio/)|
|`menu`| Menu |[`menu`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menu_role)|[`menuitem`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menuitem_role)|[APG Menu / Menubar](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)|
194
+
|`menubar`| Menubar |[`menubar`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_role)|[`menuitem`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menuitem_role)|[APG Menu / Menubar](https://www.w3.org/WAI/ARIA/apg/patterns/menu/)|
2. No explicit container `role`: UA maps behavior token to its minimum role (subject to minimum-role conditions described above).
@@ -986,29 +969,27 @@ last-focused element in a `focusgroup`, a change to sequential focus navigation
986
969
987
970
When a user navigates into a focusgroup using Tab or Shift+Tab, the user agent must:
988
971
989
-
1.**Determine direction:** "forward" for Tab, "backward" for Shift+Tab.
972
+
#### 1. **Determine direction:** "forward" for Tab, "backward" for Shift+Tab.
990
973
991
-
2.**Identify the focusgroup segment:** The set of `focusgroup` items that are reachable without crossing any [opted-out items](#opting-out) in tree order from the entry point in the direction of navigation.
974
+
#### 2. **Identify the focusgroup segment:** The set of `focusgroup` items that are reachable without crossing any [opted-out items](#opting-out) in tree order from the entry point in the direction of navigation.
992
975
993
-
3.**Apply focus priority (first match wins):**
976
+
#### 3. **Apply focus priority (first match wins):**
994
977
- If the focusgroup has a **last focused item** and the [`no-memory`](#disabling-focusgroup-memory) token is not present, and the last focused item is within the current segment, focus that item.
995
978
- Otherwise, if an item within the segment is **sequentially focusable** (e.g., has `tabindex="0"` or is a natively focusable element like `<button>`), focus the first such item in tree order (regardless of direction).
996
979
- Otherwise, if direction is "forward", focus the **first** focusable `focusgroup` item in the segment in tree order (including elements with negative `tabindex` values).
997
980
- Otherwise, if direction is "backward", focus the **last** focusable `focusgroup` item in the segment in tree order (including elements with negative `tabindex` values).
998
981
999
-
4.**Update tab navigation:** All other `focusgroup` items are not considered in sequential focus navigation order. Memory is updated to be on the newly focused item if the [`no-memory`](#disabling-focusgroup-memory) token is not present.
1000
-
982
+
#### 4. **Update tab navigation:**
983
+
All other `focusgroup` items are not considered in sequential focus navigation order. Memory is updated to be on the newly focused item if the [`no-memory`](#disabling-focusgroup-memory) token is not present.
984
+
____
1001
985
This algorithm ensures that each [focusgroup segment](#focusgroup-segments) has a single [guaranteed tab stop](#guaranteed-tab-stop), without the need for authors to manage `tabindex` values except to customize the first focused element when entering a `focusgroup`.
1002
986
1003
987
Additionally, when focus is within [native key conflict elements](#key-conflict-elements), immediate
1004
988
neighboring focusgroup items are automatically made available in the tab order to provide an
0 commit comments