🤯 Create a modal with zero line of CSS 🤯
Jérôme Pott

Jérôme Pott @mornir

About: Web Developer building websites on the Jamstack.

Location:
Switzerland
Joined:
Feb 27, 2018

🤯 Create a modal with zero line of CSS 🤯

Publish Date: Sep 24 '18
62 9

Introduction

HTML 5.2 brought us the dialog element! 🙌

For now, only Chrome implemented it, but other browser vendors will certainly follow if they want to be fully HTML-compliant. (In Firefox, it is already behind a flag.) There's also a polyfill for it.

Let's now examine this relatively new and shiny HTML element. 🔬

Demo

In the codepen below, I created a fully functional modal without writing a single line of CSS. 🤓

So, how does all this work?

Well, it is actually quite simple. We just need to use the dialog element and add the open attribute to display it (by default it is hidden). We can toggle that attribute on by using the showModal method provided on the HTMLDialogElement. We call the close method to toggle it off.

const modal = document.querySelector('#modal')
modal.showModal() // opens the modal
modal.close() // closes the modal

Enter fullscreen mode Exit fullscreen mode

You can notice a few neat things that the dialog element does automatically for us:

  • The dialog is centered in the middle of the screen.
  • The background is dimmed and elements behind the modal can't be interacted with.
  • The dialog has already basic styling (quite ugly, but more on this later).
  • The escape key closes the modal.

And by adding method="dialog" to the form tag:

  • The first interactive element (in the DOM order) is focused.
  • Upon form submission, the dialog is close and the value of the element that triggered the submit event is saved on the returnValue property of the HTMLDialogElement.

In our codepen above, both buttons trigger the closing of the modal. When the modal is closed, it emits a close event. In our demo, modal.returnValue will contain either 'yes' or 'no' (or an empty string if the user presses [escape]).

modal.addEventListener('close', () => {
    console.log(modal.returnValue) // In our case: 'yes', 'no' or ''
})

Enter fullscreen mode Exit fullscreen mode

Customization

The dialog element comes with a default user agent stylesheet, but can be fully customized. You can even change the modal backdrop in this way:

#modal::backdrop {
    background-color: rgba(0, 0, 0, 0.4)
}

Enter fullscreen mode Exit fullscreen mode

An example of customization using Tailwind CSS

Resources

In this post, I only cover some aspects of the dialog element. For detailed information about this topic, I recommend the following links:
https://alligator.io/html/dialog-element/
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
https://demo.agektmr.com/dialog/

Comments 9 total

  • Sam Thorogood
    Sam ThorogoodSep 25, 2018

    Nice post! There's also a polyfill: github.com/GoogleChrome/dialog-pol... (shameless self-promotion)

    And Firefox has an incomplete implementation behind a flag: bugzilla.mozilla.org/show_bug.cgi?...

    • Jérôme Pott
      Jérôme PottSep 26, 2018

      Thank you for your comment!😃

      I've updated my post to mention your polyfill. But I feel like the biggest “selling point” for using the dialog element is its ease of use. Personally, if I have to install a npm package and then register DOM elements, I would rather create my own modal with CSS or install a npm package like vue/react-modal if I am using a framework.

      • Sam Thorogood
        Sam ThorogoodSep 27, 2018

        Sure, but dialog is only supported in Chrome, so in my opinion it's unreasonable to ship it without a polyfill.

        I appreciate your argument, but I think it implies that you should always just create your own modal and not use the built-in one :)

        • Jérôme Pott
          Jérôme PottSep 27, 2018

          Yes, in the current state of adoption, your polyfill is the only way to use the dialog element in production.

          And if a developer uses React or Vue, he/she can easily overcome the polyfill's major limitation (stacking context) by using portals. ✌️

  • fgiraldi
    fgiraldiSep 26, 2018

    Very nice post!
    I actually don't get it on what the W3C is up to. Years of using propietary MS IE window.showModalDialog, then going into some HTML standars that ended draw back, and now this, a (brand new) implementation for the same purpose.
    I remember when browsers stopped the modal functionality because implementations where so bad. What will be the difference now?
    I suppose someone figured out how to make this modals modal to their own window parent, so now, there is no problem in having a modal dialog inside your page, if you want to switch to another tab to see another page, now you just can.
    I hope this to be a relief for all of us developers, who need some sort of synchronism in our apps, without being forced to rely on 3rd party libraries or no standard behaviours.
    Thanks a lot for the post.
    These are great news.

    • Jérôme Pott
      Jérôme PottSep 26, 2018

      Thank you for reading my post 😊
      Yes, I do think that the end goal is to set standards for better accessibility.

      About this, Jen Simmons wrote:

      It would allow Authors to remove a bunch of (sadly too often crappy and inaccessible) JavaScript from their websites. bugzilla

  • Angel Daniel Munoz Gonzalez
    Angel Daniel Munoz GonzalezSep 26, 2018

    Cool Post!
    While I do like the Idea of having a native Dialog element, It doesn't always turns to be that good, think of the select element for example, it is always a mess to style one in a good way across browsers, that you end up using a third party library that renders a consistent select element, even the MDN Docs say so:

    The <select> element is considered impossible to style consistently cross-platform. However, some styles are workable.

    I think this is one of the reasons the dialog element hasn't been rushed to implement.

    That being said, it is nice to know it could be an alternative in the future.

    • Jérôme Pott
      Jérôme PottSep 26, 2018

      Thanks for your comment 😃

      I think that the issue of styling has been taken into consideration in the design of the dialog element. It is very easy to override the default styles and it even provides a pseudo-element (::backdrop) for customizing the background.

      So in the end, it is as easy as styling a div tag, but with the added accessibility benefit.

  • harshdsdh
    harshdsdhJul 26, 2019

    Thank you so much for this. i was looking for a non css option to create a modal and this is exactly what i needed

Add comment