The dialog element

Orde Saunders' avatarPublished: by Orde Saunders

Recently I was looking for a way to present some information and settled on the <dialog> element - a browser native modal window that is a DOM element stylable with CSS.

I've never really been a fan of modal windows on webpages as they're hard (and tedious) to implement correctly so window.alert and window.confirm have been my go-to but they are extremely limited. <dialog> has changed that for me, it's really easy to work with and, as a DOM element, the options are wide open.

Here's a simple example of how I have replaced the alert functionality using <dialog>. For this I'm using ES6 modules which is how I write all my own JS these days.

In dialogue.mjs I have a basic constructor that will generate the element with usable content:

const parser = new DOMParser();

export const createDialogue = (class) => {
    const dom = parser.parseFromString(
        `
<dialog class="${class}">
    <div></div>
    <form method="dialog">
        <button>OK</button>
    </form>
</dialog>
        `,
        "text/html"
    );
    return dom.querySelector("dialog");
};

In this case I'm using a data attribute to hold some text that will be shown in the modal on click. This is in a module called modal.mjs:

import { createDialogue } from "./dialogue.mjs";
import { kebab2Camel } from "./data_attributes.mjs";

const dialogue = createDialogue("alert");
const content = document.createElement("p");
dialogue.querySelector("div").append(content);

export const init = (attribute) => {
    document.querySelector("body").append(dialogue);
    document.addEventListener("click", (e) => {
        const target = e.target;

        if (target.hasAttribute(attribute)) {
            content.innerText = target.dataset[kebab2Camel(attribute)];
            dialogue.showModal();
        }
    });
};

Then in my main.mjs I initialise it when required:

const MODAL_ATTRIBUTE = "data-modal-content";
if (document.querySelector(`[${MODAL_ATTRIBUTE}]`)) {
    import("./modal.mjs").then((tooltip) => {
        tooltip.init(MODAL_ATTRIBUTE);
    });
}

This is really easy to work with, it can be styled with CSS using the class variable passed into the constructor and, as it's just a DOM element, by holding onto a reference to it in modal.mjs it can be easily manipulated with standard DOM access methods.

There's a lot more that can be done with dialogues than this simple case, for example you can get return values from the buttons within the dialogue which can replace window.confirm, but this is another nice bit of modern browser native functionality.


Comments, suggestions, corrections? Contact me via this website