dialog elements are a great addition and I'm glad they're getting implemented, but a key part of their functionality relies on JavaScript: to open a <dialog> you need to use JavaScript to set the open attribute.
It'd be great if there was a way to make a <a> or a <button> elements capable of opening dialogs.
Precident already exists for page interactivity baked into HTML - for example <a href="#.."> can already scroll the page, and <details> elements are capable of hiding elements behind interactivity, so I think it stands to reason <dialog> elements could be opened by other page elements.
Yeah, it's somewhat weird you can close them via <form method=dialog>, but not open them in any way.
One workaround would be to utilize <input type="checkbox"> with an associated <label> element styled as a button and toggle display of the <dialog> element
<!DOCTYPE html>
<html>
<head>
<style>
#dialogInput, #dialogInput:checked ~ #dialog {
display: none;
}
[for="dialogInput"] {
appearance: button;
-webkit-appearance: button;
-moz-appearance: button;
padding: 2px;
}
</style>
</head>
<body>
<label for="dialogInput">Dialog</label>
<input type="checkbox" id="dialogInput">
<dialog id="dialog" open>
<p>Hello universe</p>
</dialog>
</body>
</html>
or to include <dialog> element as child of <details> element at HTML.
I don't think there's a very significant difference between e.g. <button opendialog="mydialog"> and <button onclick="mydialog.open()">. That is, I think HTML already has the ability to open dialogs.
IMO there are very specific and quite substantial differences with those two examples. For one, the latter cannot be used in combination with CSP headers that disable inline JavaScript. Secondly the latter example cannot be easily statically analysed - this leads to plenty of problems such as no way for accessibility tools to determine which dialog that button will open.
FWIW, we ended up creating <details-dialog>. Which as the name suggests, is a dialog dependent on details. It is now used across github.com. This was prompted by two reasons:
<dialog>It does still need JavaScript to be fully accessible, but it is interactive without. Having a native way to achieve the stacking context would definitely be much preferred, whatever it end up being.
@Malvoz a toggle would be helpful but I think it's also worth being able to choose the state you're aiming for.
I think it's worth noting the <dialog> actually has 3 states.
though you could argue modal should be an attribute of the dialog and not a method of opening it.
Currently, I do something like this
<button data-for-dialog="testDialog" open>Open dialog</button>
<dialog id="testDialog">
<h1>An example of a native Dialog element</h1>
<p>This is a dialog box and, believe it or not, it's built into HTML, sure we needed some javascript to open it but hey, it's a start.</p>
<button data-for-dialog="testDialog" close>Close dialog</button>
</dialog>
and then have some JS like so
const dialogTriggers = document.querySelectorAll(`[data-for-dialog]`);
for (let trigger of dialogTriggers) {
const dialog = document.getElementById(trigger.dataset.forDialog);
trigger.addEventListener('click', () => {
trigger.hasAttribute('open') && dialog.showModal();
trigger.hasAttribute('close') && dialog.close();
});
}
I think it would be helpful to be able to do something like this and have it work.
<button for-dialog="testDialog" open>Open dialog</button>
<dialog modal id="testDialog">
<h1>An example of a native Dialog element</h1>
<p>This is a dialog box and, believe it or not, it's built into HTML, sure we needed some javascript to open it but hey, it's a start.</p>
<button for-dialog="testDialog" close>Close dialog</button>
</dialog>
Where you have the desired state is an atribute of your controller, or it toggles if nothing if present.
And where the dialog is a modal or not depending on an attribute on the dialog not how it's opened.
I would propose the following addition to the standard: an opens, opensModal and closes attribute that can be added to any HTML element and takes the id of an element to add to or remove from the open/openModal attribute; when both an opening and close attribute are set on the same element, it will perform as a toggle switch.
This will be useful for both existing (details/summary, dialog) as well as future interactive elements that can be opened/closed. A polyfill will also be pretty simple:
if ('opens' in document.createElement('button')) {
document.addEventListener('click', (ev) => {
let target = ev.target;
while (target) {
if (!target.getAttribute) {
continue;
}
const targetCloses = target.getAttribute('closes');
const targetOpens = target.getAttribute('opens');
const targetOpensModal = target.getAttribute('opensModal');
const targetOpensAny = targetOpens || targetOpensModal;
const attribute = targetOpensModal ? 'openModal' : 'open';
if (targetOpensAny && targetOpensAny === targetCloses) {
const toggle = document.getElementById(targetOpensAny);
if (toggle.hasAttribute(attribute)) {
toggle.removeAttribute(attribute);
} else {
toggle.setAttribute(attribute, true);
}
} else {
if (targetOpensAny) {
const open = document.getElementById(targetOpensAny);
open.setAttribute(attribute, true);
}
if (targetCloses) {
const close = document.getElementById(targetCloses);
close.removeAttribute('open');
close.removeAttribute('openModal')
}
}
target = target.parentElement;
}
});
}
I appreciate all these proposals; however, I think it's more likely that we'll end up removing the dialog element entirely, as it only has a single implementer and is thus retrospectively failing to meet the criteria of https://whatwg.org/working-mode#additions. Given this, proposals to expand an already-failing feature are unlikely to get much engagement...
I believe Firefox has the feature behind a flag but were waiting to see how inert progressed before going live.
That does't match my understanding, but be that as it may, stalled implementations don't really help a feature make progress either.
I've had success implementing much of what I need dialog to be by just using CSS, so I don't see much reason to consider this worth abandoning.
Implementing this in CSS is possible, but doing so in an accessible way is really difficult to get right. So a semantic element making this easier would be an improvement over the current state.
While I agree that the proposal for dialog is lacking, the idea of having a semantic element for notifications, modals, etc. should not be dismissed easily.
I honestly don't understand what's the delay in implementing this. I have hardly worked on a project where I didn't need to create a dialog and resorted to custom JS/CSS. A dialog with custom HTML content should be part of the spec and should have been part of the spec since 2013.
A dialog with HTML content is indeed part of the spec. Putting things in the spec however does not magically compell browsers to implement it. Only Chrome has implemented it so far, and other browsers have shown no movement toward doing so in some time. Your exasperation is probably better directed toward their bug trackers, instead of toward the bug tracker of a specification that you seem to have not read.
FYI; there has been some movement from Firefox in implementing <dialog> quite recently:
https://bugzilla.mozilla.org/show_bug.cgi?id=840640
https://bugzilla.mozilla.org/show_bug.cgi?id=1522094
I think you may be over-optimistic there. The last time any code related to dialog landed was a month ago, in which someone added a pref to enable the incomplete implementation, but it was then immediately backed out by bots. The last time someone actually landed implementation code was 2016-12-11, if I am reading correctly. This is not the sort of implementation interest that marks a sustainable feature :(.
I think you may be over-optimistic there. The last time any code related to dialog landed was a month ago, in which someone added a pref to enable the incomplete implementation, but it was then immediately backed out by bots. The last time someone actually landed implementation code was 2016-12-11, if I am reading correctly. This is not the sort of implementation interest that marks a sustainable feature :(.
Apart from the previous Firefox news, even also the WebKit teams explicitly mention it in their roadmap 2020 draft .
Most helpful comment
Implementing this in CSS is possible, but doing so in an accessible way is really difficult to get right. So a semantic element making this easier would be an improvement over the current state.
While I agree that the proposal for dialog is lacking, the idea of having a semantic element for notifications, modals, etc. should not be dismissed easily.