[BUG] dcc.Dropdown: hidden focus-target input is focusable inside aria-hidden and can overflow its wrapper
Maintainer antworten meist innerhalb von 2 Tagen
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 56/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- css, playwright, python, react, typescript
- Bereich
- accessibility, frontend
Rechercherichtung
Starte in components/dash-core-components/src/fragments/Dropdown.tsx (das versteckte input.dash-dropdown-focus-target mit aria-hidden und tabIndex) und src/components/css/dropdown.css (dessen absolute Positionierung, unbegrenzte Breite). Reproduziere mit dem Minimal-Layout im Issue und prüfe dabei document.documentElement.scrollWidth und führe axe-core für die aria-hidden-focus-Verletzung aus. Fertig, wenn das Fokusziel die Seite nicht mehr verbreitert und sich kein fokussierbarer Inhalt innerhalb von aria-hidden befindet, wobei das Safari-Tab-Verhalten, auf das die Umgehung abzielt, beibehalten wird; prüfe, ob die vorhandenen Dropdown-Tests in der Test-Suite von dash-core-components weiterhin bestehen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Thank you for Dash!
Describe your context
dash 4.5.0rc0
(the same code is on dev today: components/dash-core-components/src/fragments/Dropdown.tsx and src/components/css/dropdown.css)
- OS: Linux
- Browser: Chromium 151 (headless, via Playwright) with axe-core
Describe the bug
The hidden input.dash-dropdown-focus-target that dcc.Dropdown renders (the Safari tab-order workaround) causes two problems:
-
It is focusable inside
aria-hidden. It hasaria-hidden="true"andtabIndex={0}(while the trigger<button>istabIndex={-1}), so the only tab stop for every dropdown is hidden from assistive technology. axe-core reportsaria-hidden-focus(serious) once perdcc.Dropdownon the page: "Focusable content should be disabled or be removed from the DOM". -
It can widen the page. Its CSS is only
position: absolute; opacity: 0; pointer-events: none;, so it keeps the browser's default input width (about 215px in Chromium) and is anchored atleft: 0of the wrapper. A dropdown narrower than that, near the right edge of a flex row, pushes the input past the viewport: in our app a 600px-wide viewport gotdocument.documentElement.scrollWidth === 648(horizontal scrolling on mobile). Addingmax-width: 100%(orwidth: 100%/inset: 0) to.dash-dropdown-focus-targetfixes it; we use this override for now:.dash-dropdown-wrapper .dash-dropdown-focus-target { max-width: 100%; }
Minimal example:
from dash import Dash, dcc, html
app = Dash(__name__)
app.layout = html.Div(
[html.Div(style={"flex": "1"}), dcc.Dropdown(["a", "b"], placeholder="Pick", style={"width": "140px"})],
style={"display": "flex", "width": "100%"},
)
if __name__ == "__main__":
app.run()
At a 200px-wide viewport, document.documentElement.scrollWidth is 237 because of the focus input, and axe-core reports one aria-hidden-focus violation on it.
Expected behavior
- No focusable element inside
aria-hidden. For example, droparia-hiddenfrom the workaround input and give it the dropdown's accessible name, or make the trigger button itself the tab stop where the browser supports it. I don't know which works best with the Safari behaviour the workaround targets. - The hidden input never takes more space than its wrapper (
max-width: 100%indropdown.css).
Screenshots
n/a
- Vorherrschende Sprache
- Python
- Sterne
- 24.4k
- Forks
- 2.3k
- Ø Merge
- 2 T. 19 Std.
- Gemergte PRs (30 T.)
- 26
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Hat eine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus plotly/dash
-
P2 plotly-internal size: 1 task
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 2 Tagen
-
Extract graph schema validation into properly named testEvtl. vergeben @Nice6042 hat das vor 61 Tagen übernommen. Offengood first issue P3 size: 1 task
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
plotly/dash#3735 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 2 Tagen
-
P3 plotly-internal size: 10+ task
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 30/100
plotly/dash#4040 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 2 Tagen
-
Drop Python 3.9 SupportOffenP2 plotly-internal size: 5 task
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
plotly/dash#4038 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 2 Tagen
-
[BUG] Setting children to None leaves removed components registered: their callbacks keep firing and the subtree can never be mounted againEvtl. vergeben @0d00ciallo0721 hat das vor 7 Tagen übernommen. Offenbug P3 size: 3
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 62/100
plotly/dash#4033 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 2 Tagen
Ähnliche Issues
-
Atomic append fails to create a missing fileEvtl. vergeben @harbinresearcher hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
fabiocaccamo/python-fsutil#201 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
task
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
danparshall/claude_researcher#87 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
GhostManager/Ghostwriter#998 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
datajoint/datajoint-python#1586 ·
Maintainer antworten meist innerhalb von 1 Tag