Using <details> for menus and dialogs (2019)
css-tricks.com
css-tricks.com
Full working example of a modal dialog:
<dialog id="dialog">
<form method="dialog">
What is your favorite color?
<input name="color">
<button>Save</button>
</form>
</dialog>
<button onclick="dialog.showModal()">
Show dialog
</button>
The dialog element is fully supported in Chrome/Edge and Firefox nightly, and there's a polyfill[3] for the others.[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...
[2]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/me...
Personally I’d rather that the toggle was available as an activation behaviour, and this is an open issue for the HTML standard. https://github.com/whatwg/html/issues/3567
Not really, for either menus or non-modal dialogs:
“The details element represents a disclosure widget from which the user can obtain additional information or controls.”
https://html.spec.whatwg.org/multipage/interactive-elements....
On browsers, it's at 73% native support on caniuse, and the polyfill is high-quality, by the Chromium team.
As far as looks, it's all fully styleable with CSS so you can make it look however you like.
Alternatively: it works in Blink, but nowhere else.
Historically it's more likely that an unpopular tag will be removed from the HTML spec and removed from browsers than JS will lose compatibility with your code.
For example, a JS flashing text effect from 25 years ago still works. <blink> tags don't.
Most tags that are deprecated in the spec aren't removed (eg marquee) but you shouldn't assume something in the spec will be available forever.
And nowadays, even if dialog happened to be deprecated, you could always continue to support it using a custom element if you really needed to (which probably wouldn't be the worst approach even if you were building it from scratch, to be honest).
But overall I feel this approach has worked well over the years. With jQuery for example, I only learned enough to get by working in those codebases, but I committed to internalized all of the standardized DOM methods and Array methods and naive XHR workings. Now in these modern times, jQuery still _works_, but whatever I came to know of it is no longer very useful to me, day to day.
https://groups.google.com/g/mozilla.dev.platform/c/gqi4MDQDw...
Meanwhile Safari doesn't support it at all.
The stats on caniuse are skewed by Chromium as usual.
As far as I can tell the rendering is currently hacky (i.e. it doesn't follow the spec but achieves the same visual result) and the implementation is supposed to be tied to the `inert` attribute, which isn't currently implemented in FF. This may not matter to most users but if left as-is would result in cross-browser compatibility issues.
The significant outstanding blocker for FF is re. focus twiddling for better a11y, per recent discussion at whatwg/html#5678, c.f. bugzilla#1660271 & #1701230, and this is hardly boiling-the-oceans stuff.
I'm excited for <dialog>, it's a survivor, and a great simplifier - particularly of dev conversations - and I recommend it (even with interim polyfill) to all and sundry.
I would avoid using it.
[0]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/me...
of course, much of the rest is experimental and unimplemented.
Window.this.modal(<info>Hello world</info>);
Window.this.modal(<alert>Hello world</alert>);
let r = Window.this.modal(<question>Hello world</question>);
will create real modal dialogs (as separate desktop windows).A working reference implementation can be found here [1]. Additionally, I ended up using a version of this on my personal site [2]. This works on stable versions of Chrome, Edge, Firefox, and Safari.
One thing to be careful of when using `<details>` in interesting ways: accessibility. At a minimum, I encourage folks to make sure that screen readers work as expected.
[1] https://codepen.io/devadvance/pen/bGBvvWv
[2] https://github.com/devadvance/devadvance.github.io/blob/mast...
And even when we have an element, most devs end up replacing it with a JS version anyway. The HTML select element is a good example. The built in one almost always gets replaced with something that looks nicer and has more features like icon support and themeability
While I agree all these API need to be carefully crafted, this one is very much a no brainer. Mozilla (and Apple) should be at the forefront of these native UI improvements, because it allows the developer to rely on standard behavior rather than rolling out one's own broken UX.
> And even when we have an element, most devs end up replacing it with a JS version anyway.
No they don't.
> The HTML select element is a good example
Yes, because it's almost impossible to style it or make it display some custom content that isn't a line of text. The problem isn't its existence, it's its shortcomings because it was basically speced 25 years ago. I'll take a standard widget that I know will work in an expected fashion across many devices rather than someone's personal library in GitHub that is broken in subtle ways. That's the idea behind standards.
I was on a site not long ago, which displayed a modal pop up, well the page was going up and down frenetically every half second because the developer probably used a library that wasn't tested on the browser I used. the UX was completely broken. With standards, if a polyfill is broken then you have a good argument to confront its developer with (if I can put it that way).
How do we fix it though? It clearly needs major changes and improvements, but those can't be made without breaking compatibility. Do we add a select2 element? modern-select?
I don't know, but looking at the timeline for other features to be implemented that virtually (if not literally) every web dev has cried out for since year dot like vertical align and grid, I'm putting my money on a new select element around 2035.
Then why don’t we improve the capabilities of the built in one?
I’ve always found this odd, JavaScript and CSS are constantly improving, and there’s a steady stream of new things to make development easier. But no-one seems to care about improving HTML, despite being by far the best focus of efforts.
Rich functionality via new/improved HTML tags would be accessible, performant, would work without JavaScript, and in many cases could be easily polyfilled.
I’ve also used them for modals and slideovers. Use in conjunction with an [open] selector and adjacency combinators for maximum utility.
See also: <dialog>, already in Chrome, and for which Firefox’s support is looking good in nightly builds; and the :focus-within pseudo-class.
From the department of “You might not need (much) JavaScript”, which has come a long way from checkbox hacks.
To quote the article:
>tl;dr - <summary> is a button and buttons eat semantics
[1]: https://daverupert.com/2019/12/why-details-is-not-an-accordi...
That second link is great, and this sentence caught my attention: "At the risk of being a broken record; HTML really needs <accordion> , <tabs>, <dialog>, <dropdown>, and <tooltip> elements." At first glance, that sure would simplify a lot of the work I've done in the past.
I’m fairly certain it’s a shadow DOM implementation detail. While it technically toggles a binary state and is probably more semantically similar to a checkbox, I think the way it’s exposed to web APIs makes that either impractical or non-obvious.
Conceptually the summary is a toggle button: you click it to toggle the display state of the details element.
There are some other cases where certain newer features like display: contents also hide content from assistive tools. I’m pretty sure some of these are being worked on, but don’t have great recall of whether that includes details/summary.
Apparently this element is still implemented in Shadow-DOMy way [1]. So the effort was worth something after all, I guess.
[1] https://github.com/WebKit/WebKit/blob/main/Source/WebCore/ht...
I recently implemented a design comp with plain HTML/CSS that had several expandable sections and dialogs and for some of them `summary` was a good choice but other times a combination of `:hover`, `:focus` and `:focus-within` (while making sure to only hide the content visually because these interactions don't play well with screenreaders) ended up being a better choice.
When considering the options, keep in mind that although "JS interactions are inaccessible" is widely held as common knowledge, it's not an absolute truth and neither is the inverse "non-JS interactions are never inaccessible". It's important to understand the accessibility implications of what you're doing. With JS this means you may have to do additional things (e.g. dynamically setting ARIA attributes), without CSS this means you have to avoid doing certain things altogether (e.g. toggling `display: none` to hide content).