The `<dialog>` element has been around for years, and it was finally approved by the W3C in the HTML 5.2 spec. But how does it work? Is it fully supported?—and can we finally quit using `role=”dialog”`?
The answer to most of these questions is, “No.” In this article I will get into why, and in the next article I’ll show you the pattern to use instead.
Some of the completely dope features that the `<dialog>` is supposed to offer:
- Set focus to the first focusable element (unless you use `tabindex` to override)
- A pre-styled CSS backdrop and horizontal positioning
- Listens for Esc key to close the dialog
- When it closes, it can pass a data string to the `dialog.close()` method
I know, but don’t get excited just yet. Unfortunately, this native component still doesn’t have the minimal support to get developer backing.
Chrome (macOS+Windows) and the new Chromium-based Edge browser support `<dialog>` nicely, but Firefox is a mess. Even with a feature flag enabled in Firefox preferences, and with polyfill support, the dialog element fails to trap keyboard focus – and in VoiceOver (macOS), it fails to trap screen reader focus as well. Safari does not support it at all, and don’t even get me started with Internet Explorer.
|Accessibility Behavior||Windows JAWS-Chrome||Windows JAWS-Firefox||Windows JAWS-Edge||Windows NVDA-Chrome||Windows NVDA-Firefox||Windows NVDA-Edge||Windows JAWS/NVDA-IE||macOS VO-Chrome||macOS VO-Firefox||macOS/iOS VO-Safari|
|Announce Dialog Context||Pass – “Modal dialog”||Pass – “Dialog”||Pass – “Modal dialog”||Fail – null||Fail – null||Fail – null||Fail – null||Fail – “Group”||Fail – “Group”||Fail – null|
|Hide & Show||Pass||Pass||Pass||Pass||Pass||Pass||Fail||Pass||Pass||Fail|
|Trap Keyboard Focus||Pass||Fail||Pass||Pass||Fail||Pass||Fail||Pass||Fail||Fail|
|Trap Screen Reader Focus||Pass||Pass||Pass||Pass||Pass||Pass||Fail||Pass||Fail||Fail|
The MDN specs for the dialog element claim that there is a polyfill to extend support for browsers without the `<dialog>` element, but it confers no noticeable improvement.
The MDN documentation also puts Firefox behind a feature flag (about:config, dom.dialog_element.enabled), but let’s take a look at the result of enabling this property.
Windows/JAWS on Firefox (w/polyfill)
- Feature flag = “false”: (1) Can’t handle `tabindex`, (2) Traps keyboard and screen reader focus
- Feature flag = “true”: (1) OK with `tabindex`, (2) Traps screen reader focus, but NOT keyboard focus
Windows/NVDA on Firefox (w/polyfill)
- Feature flag = “false”: Works OK
- Feature flag = “true”: DOES NOT trap keyboard focus
macOS/VoiceOver on Firefox (w/polyfill)
- Feature flag = “false”: (1) Traps keyboard and screen reader focus, (2) Announces “dialog” role
- Feature flag = “true”: (1) Traps screen reader focus, but NOT keyboard focus, (2) DOES NOT announce “dialog” role, announces “group”
In short, the feature flag that is supposed to fix the issue makes the issue marginally worse, at best. In a way, it performs an abuse on the experience, and in a very small minority of cases that abuse builds some valuable character traits – but overall, the juice isn’t worth the squeeze.
Even when Safari adds nominal support for the element, these lingering discrepancies will give developers pause when considering use of the `<dialog>` element for a wide audience. For the same reason, I won’t get into how to use it; plenty of prior authors have already done that (see References below). Instead, the next article will outline the still-best-case-ideal solution.
- <dialog>: The Dialog Element – MDN Web Docs
- The Current State of Modal Dialog Accessibility – The Paciello Group
- Some Hands-On with the HTML Dialog Element – CSS Tricks
- Having an Open Dialog – ScottOhara.me
- Native Modals on the Web Using the HTML Dialog Element
- Meet the New Dialog Element – KeithJGrant
- Implement the HTML5 Dialog Element – Bugzilla