angular / angular/components

bug(a11y): FocusTrap doesn't match browser/spec tab order in relation to Shadow DOM

Offen
#32,265 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
area: cdk/a11y P3
Vorherrschende Sprache
TypeScript
Sterne
25k
Forks
6.8k
Ø Merge
1 T. 8 Std.
Gemergte PRs (30 T.)
91

Beschreibung

_EDIT: Removed the regression questions, it's not a regression_

### Description

A project I work with uses a component library based on https://lit.dev with `CUSTOM_ELEMENTS_SCHEMA`. They sometimes have regular, tabbable elements (``, ``) in their Shadow DOM and participate in the browser tab order as expected.

However, the CDK `FocusTrap` machinery and the `_getFirstTabbableElement` / `_getLastTabbableElement` don't quite consider enough of the [sequential focus navigation]. That means that focus trapping in a dialog only works it there's at least one *focusable area* not in a Shadow DOM.

For performance reason, I don't think it's necessary to build up the full [sequential focus navigation order]. It'd probably be sufficient to use the [`"DOM"` selection mechanism](https://html.spec.whatwg.org/multipage/interaction.html#selection-mechanism-dom) i.e. find the first/last [suitable sequentially focusable area] element in [shadow including tree order] (host - shadow dom - light dom).

[shadow including tree order]: https://dom.spec.whatwg.org/#concept-shadow-including-tree-order
[suitable sequentially focusable area]: https://html.spec.whatwg.org/multipage/interaction.html#suitable-sequentially-focusable-area
[sequential navigation search algorithm]: https://html.spec.whatwg.org/multipage/interaction.html#sequential-navigation-search-algorithm
[sequential focus navigation]: https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation
[sequential focus navigation order]: https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-order

### Reproduction

StackBlitz link: https://stackblitz.com/edit/components-issue-starter-2e9thbl6?file=src%2Fmain.ts
Steps to reproduce:
1. Click in the preview window, preferably somewhere in the top part of the red area.
2. Tab to see the focus (outline) on the button in the red area
3. Tab to see the focus on the hidden trap element
4. Tab to see the focus (outline) on the button in the blue area
5. Keep Tabbing to see the focus actually get trapped

### Expected Behavior

The focus should remain trapped in the red area

### Actual Behavior

The focus moves past the red area, to an invisible item and then only gets trapped in the blue area.

### Environment

- Angular: 19, 20
- CDK/Material: 19, 20
- Browser(s): Edge, Firefox
- Operating System (e.g. Windows, macOS, Ubuntu): Windows 11 Enterprise

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne mit der CDK FocusTrap-Logik und ihren Methoden _getFirstTabbableElement/_getLastTabbableElement und reproduziere dann das Verhalten anhand des verknüpften StackBlitz-Beispiels. Vergleiche die Traversierung mit der shadow-including tree order und überprüfe, dass der Fokus innerhalb des rot markierten eingeschlossenen Bereichs bleibt, anstatt sich durch das verborgene Trap-Element zu bewegen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
angular, typescript
Bereich
accessibility, frontend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.