# data[].attributes.title
Dialog dilemmas and modal mischief (7 mins edition w/transcript)

# data[].attributes.blurb.html
Our design systems commonly feature components that show on top of other content: tooltips, date pickers, menus and teaching UI, to name just a few. There are many ways to build them, and new features in the web platform are about to make this a whole lot easier. You might not even need JavaScript. In this talk, you’ll learn all about dialogs, including the new ‘popover’ attribute, “modality” and using the top layer.

# data[].attributes.slidedeck.data[].slides[].desc.html
Hello Amsterdam! Let’s talk about dialogs and popovers.

# data[].attributes.slidedeck.data[].slides[].desc.html
The web used to be just linear content…

# data[].attributes.slidedeck.data[].slides[].desc.html
but these days we make content overlap in all sorts of ways.

# data[].attributes.slidedeck.data[].slides[].desc.html
I want to talk to you about two very exciting bits of the HTML specification: the dialog element, which has been around for a while, and the popover attribute, which is very new and landed in Chrome stable just last week. Other browers are working on it and the spec is still undergoing tweaks and improvements.

# data[].attributes.slidedeck.data[].slides[].desc.html
Examples of popovers include teaching UI, where a web page shows the user how to use a thing, in this case the audio player at The Economist.

They are used in all sorts of ways, also to advertise products.

# data[].attributes.slidedeck.data[].slides[].desc.html
Like Microsoft did the other day, showing an ad for Excel while I was in a serious business meeting. (screenshot of Teams meeting with popover advertising Excel)

# data[].attributes.slidedeck.data[].slides[].desc.html
This morning it urged me to be my expressive self (screenshot of another meeting where a popover talks about creating an avatar with that phrasing)

# data[].attributes.slidedeck.data[].slides[].desc.html
I prefer what Slack does, when you hover your own image it tells you you look nice today.

Okay, so what are these patterns…

# data[].attributes.slidedeck.data[].slides[].desc.html
The dialog element exists to build dialogs, it has built in dialog semantics and a modal setting (so it’s different from divs with just that role).

# data[].attributes.slidedeck.data[].slides[].desc.html
Using this element will give you two methods, showModal() to show it as a modal, and show to show it as a non modal, that you can call on the element.

# data[].attributes.slidedeck.data[].slides[].desc.html
Popover is an attribute, it adds a set of behaviours to an element.

# data[].attributes.slidedeck.data[].slides[].desc.html
With popover you can build things like content pickers, form element suggestions, action menus, listboxes and, as shown before, teaching UI.

# data[].attributes.slidedeck.data[].slides[].desc.html
You don’t neded JavaScript to add toggling behaviour… basically to make a popover work, add the popover attribute to any element.

# data[].attributes.slidedeck.data[].slides[].desc.html
This makes it a popover.

# data[].attributes.slidedeck.data[].slides[].desc.html
Then add a unique ID

# data[].attributes.slidedeck.data[].slides[].desc.html
and refer to it from the button using the popovertarget attribute. That’s it, the button will now toggle the popover.

# data[].attributes.slidedeck.data[].slides[].desc.html
Of course you can do it via script too, with the showPopover method, for instance if you want to time it, like I think Microsoft did to me in Teams, as that appeared and disappeared without any action from me.

# data[].attributes.slidedeck.data[].slides[].desc.html
Looking at these patterns and working on popover at the Open UI CG, I kept thing, wait, how are these patterns actually different? It’s nuanced. I want to take you through a couple of axes on which they are different.

# data[].attributes.slidedeck.data[].slides[].desc.html
The first is modal vs non modal.

# data[].attributes.slidedeck.data[].slides[].desc.html
Something is modal when it is the only thing a user can interact with. Everything else is blocked from interaction, can’t click stuff, tab to it, select it, etc.

A good use case is when you’ve decided to track your users and need to, by European law, get their consent. Can’t really place any cookies before you have a yes, don’t really want to let the user go ahead without the tracking.

# data[].attributes.slidedeck.data[].slides[].desc.html
An example of a non modal dialog is a menu, like in this CMS where you can change some options for an image.

# data[].attributes.slidedeck.data[].slides[].desc.html
Or a chat widget that appears on a train booking UI. Chances are your users want to continue doing other stuff on the page and need access to that.

# data[].attributes.slidedeck.data[].slides[].desc.html
Then, dismissing our component…

# data[].attributes.slidedeck.data[].slides[].desc.html
sometimes that happens explicitly like when there is a button to close your dialog.

# data[].attributes.slidedeck.data[].slides[].desc.html
And then there’s light dismiss, when something disappears kind of when it has to, like in Google Docs when you’re choosing a font and click outside of that font chooser, it just goes away and that feels natural.

# data[].attributes.slidedeck.data[].slides[].desc.html
Next is layering.

# data[].attributes.slidedeck.data[].slides[].desc.html
With z-index you can control the order in which elements appear that are in the same place.

# data[].attributes.slidedeck.data[].slides[].desc.html
If one thing has a z-index of 1

# data[].attributes.slidedeck.data[].slides[].desc.html
and another a z-index of 2, that last one appears on top of the first. And of course we have all seen bigger numbers than this.

# data[].attributes.slidedeck.data[].slides[].desc.html
The top layer, then, sits on top of all of that. It’s a layer of its own, so while all of your z-indexing happens in the main document, the top layer is kind of a sibling of your root element.

# data[].attributes.slidedeck.data[].slides[].desc.html
Next, some of your elements may have a backdrop.

# data[].attributes.slidedeck.data[].slides[].desc.html
You get these for free from the browser, if your element is in the top layer. It is styleable with ::backdrop, so you can do all sorts of blurring, colouring and semi transparancy.

# data[].attributes.slidedeck.data[].slides[].desc.html
Then the last one is the keyboard focus trap, sometimes you want to prevent users from tabbing outside of your component.

# data[].attributes.slidedeck.data[].slides[].desc.html
This is always a temporary thing, for instance when it’s a modal overlay or something like a complex calendar widgets that would be inconvenient to tab outside of.

# data[].attributes.slidedeck.data[].slides[].desc.html
So that’s a bunch of differences that can exist between dialogs and popovers. Let’s look at how they relate in turn.

# data[].attributes.slidedeck.data[].slides[].desc.html
Dialog elements with showModal(), I’ll just say modal dialogs now, are modal. Dialogs with show() and popovers are non-modal.

# data[].attributes.slidedeck.data[].slides[].desc.html
Popovers of the auto type, which is the default, have light dismiss. Popovers of the manual type don’t, they need to explicitly dismiss, the same goes for any dialogs.

# data[].attributes.slidedeck.data[].slides[].desc.html
Layering then… popovers and modal <dialog>s are in the top layer, for other dialogs you’ll have to set up a z-index.

# data[].attributes.slidedeck.data[].slides[].desc.html
These top layer elements are also the ones that get a browser provided backdrop. Do note though, if your’re considering a backdrop for a popover, chances are you might actually want a modal dialog, because if you’re obscuring the background you’re usually kind of making it unavailable, so why not go full modal? (There are use cases, but not many)

# data[].attributes.slidedeck.data[].slides[].desc.html
Lastly, browser provided keyboard focus traps, they come with modal <dialog>s.

# data[].attributes.slidedeck.data[].slides[].desc.html
To understand better when to use <dialog> and what accessibility pitfalls could be involved, I recommend Scott O’Hara’s posts on dialogs, including his latest on using <dialog> reasonably.

# data[].attributes.slidedeck.data[].slides[].desc.html
There is also a great post from Adrian Roselli who noted that if you’re using popovers, you should also replace dialogs with official modal <dialog>s as then they’re both in the top layer.

# data[].attributes.slidedeck.data[].slides[].desc.html
Then a quick note on support… popover just shipped in Chrome and will come to Edge soon, is in Safari Tech Preview and is in active development in Firefox.

# data[].attributes.slidedeck.data[].slides[].desc.html
Dialog is supported pretty much everywhere.

# data[].attributes.slidedeck.data[].slides[].desc.html
so, in summary, a <dialog> :

can do modal and non-modal dialogs

only top layer if modal

built in dialog role

in browsers today

whereas a popover:

non-modal components only

can light dismiss

always in top layer

no built in role

can open/toggle/close without JavaScript

in development

# data[].attributes.slidedeck.data[].slides[].desc.html
There are still some open questions re popovers, including how to position them (use a JS library now, probably anchor positioning later when it is in browsers), semantics (I have a blog post on this at hidde.blog/popover-semantics) and other somewhat trickier use cases we’re working on at Open UI, like tooltips.

# data[].attributes.slidedeck.data[].slides[].desc.html
Thanks for your attention! I’ll share these slides online, am hdv everywhere, and if you want to read more on what I shared today at your own pace, check out my blog post on hidde.blog/dialog-modal-popover-differences, find me in the break or slide in my DMs.

# data[].attributes.resources.data[].title
Use the dialog element (reasonably) by Scott O’Hara

# data[].attributes.resources.data[].title
Brief Note on Popovers with Dialogs by Adrian Roselli

# data[].attributes.resources.data[].desc.html
Suggests only using popover if also building modal dialogs exclusively using <dialog>, so that both popovers and modal dialogs are in top layer. Combining popover with role=dialog-based modal dialogs, would cause the popover to be above whatever is in the dialog.