TIL – HTML Dialog Element

#TIL

Today I learned that HTML has a native modal, known as the <dialog> element.

The HTML element represents a dialog box or other interactive component, such as a dismissible alert, inspector, or subwindow.

AN HTML POP UP? NO W…


This content originally appeared on DEV Community and was authored by James Cox

#TIL

Today I learned that HTML has a native modal, known as the <dialog> element.

The HTML element represents a dialog box or other interactive component, such as a dismissible alert, inspector, or subwindow.

AN HTML POP UP? NO WAY! (yes way).

As always, I demonstrate the usage in React.js, which means that some functionality translates directly, and other functionality does not. For example, according to the docs:

The ::backdrop CSS pseudo-element can be used to style behind a element when the dialog is displayed with HTMLDialogElement.showModal(). For example, to dim unreachable content behind the modal dialog.

As you will see in a moment, using a <dialog> in React requires a little bit of a different usage to dim the background. But, truthfully I think it is still easier than with vanilla JS.

The Modal

Looks great, doesn't it? And you will see in just a moment that the necessary code is relatively simple!

The Code

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [isOpen, setIsOpen] = useState(false);

  const openDialog = () => {
    setIsOpen(true);
  };

  const closeDialog = () => {
    setIsOpen(false);
  };
  return (
    <div className="App">
      <h1>HTMLs Native Dialog</h1>
      <h2>A simple modal</h2>

      {isOpen && (
        <>
          <div className="overlay" />
          <dialog open>
            <p>BOOM</p>
            <p>And just like that youve got a modal</p>
            <p>
              Easy peezy lemon squeezy{" "}
              <span role="img" aria-label="lemon emojis">
                ???
              </span>
            </p>
            <button onClick={closeDialog}>Close</button>
          </dialog>
        </>
      )}
      <button className="open-btn" onClick={openDialog}>
        Open Dialog
      </button>
    </div>
  );
}

Breaking it Down

The open or closed state of the modal is handled by the useState hook provided by React and toggled by the openDialog() and closeDialog() functions.

import { useState } from "react";

...

const [isOpen, setIsOpen] = useState(false);

const openDialog = () => {
  setIsOpen(true);
};

const closeDialog = () => {
  setIsOpen(false);
};

The HTML for a <dialog> element looks something like:

<dialog open>
  <p>BOOM</p>
  <p>And just like that youve got a modal</p>
  <p>
    Easy peezy lemon squeezy{" "}
    <span role="img" aria-label="lemon emojis">
      ???
    </span>
  </p>
  <button onClick={closeDialog}>Close</button>
</dialog>

The most import part of the above code is the open property in the opening <dialog> tag, written as <dialog open>. That's how the browser knows to display the modal.

And the full return statement with the conditional render handled by the isOpen property in state.

return (
    <div className="App">
      <h1>HTMLs Native Dialog</h1>
      <h2>A simple modal</h2>

      {isOpen && (
        <>
          <div className="overlay" />
          <dialog open>
            <p>BOOM</p>
            <p>And just like that youve got a modal</p>
            <p>
              Easy peezy lemon squeezy{" "}
              <span role="img" aria-label="lemon emojis">
                ???
              </span>
            </p>
            <button onClick={closeDialog}>Close</button>
          </dialog>
        </>
      )}
      <button className="open-btn" onClick={openDialog}>
        Open Dialog
      </button>
    </div>
  );

Why Should I Care?

The cool and most important thing about the <dialog> element is better accessibility. Sure, you can build your own modal, but then you've got to work extra hard to make it available to screen readers and other accessibility tools.

Another cool benefit is not having to add a bunch of z-index properties to your CSS in order to properly display the modal and any overlays you wish to add. "Modal behaviour" is baked right into the <dialog> element.

Added accessibility AND easier styling capabilities? Sounds like a WIN-WIN to me!

The CSS

Curious how I personally styled my modal and overlay? Here is the full CSS file:

.App {
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
  color: white;
  background-color: rgb(0, 0, 0);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}

body {
  background-color: black;
}

dialog {
  margin-top: 8rem;
  width: 75%;
  color: white;
  background-color: black;
  border: 3px solid rgb(72, 70, 224);
}

button {
  background-color: rgb(72, 70, 224);
  color: white;
  border: none;
  padding: 0.5rem;
  border-radius: 0.5rem;
  cursor: pointer;
  font-size: 1rem;
  font-weight: bold;
}

button:hover {
  background-color: rgb(66, 247, 207);
  color: black;
}

.open-btn {
  width: 75%;
}

.overlay {
  position: fixed;
  margin: 0;
  top: 0;
  width: 100%;
  height: 100vh;
  background-color: rgba(9, 22, 39, 0.7);
}

@media only screen and (min-width: 500px) {
  dialog {
    width: 18rem;
  }

  .open-btn {
    width: 10rem;
  }
}

The Overlay

The only thing I added that that doesn't come "baked in" was the overlay. I got creative with my solution, but I would not call it "difficult" or "complex". Inside my conditional render of the <dialog> element I added <div className="overlay" />. And simply styled with CSS:

.overlay {
  position: fixed;
  margin: 0;
  top: 0;
  width: 100%;
  height: 100vh;
  background-color: rgba(9, 22, 39, 0.7);
}

Think of it as stretching a layer of slightly-transparent color across the entire screen when isOpen is true.

Conclusion

Check out this great Shopify article that features this and other useful HTML native elements. The <dialog> element is number 6 in the article and I really liked tihs part:

Does it work?
The does a slightly more complex thing…and does it well. Browser support is somewhat patchy (notably no Internet Explorer, and Safari is pending at the time of writing), but there is a polyfill.

Is it accessible?
Support is quite good, but it does need a little ARIA support to go to production. What's really good about the element is that most accessibility support is built in, making it a far better starting point than having to create your own fixed inline custom dialog component.

I hope you enjoyed my article on this awesome HTML element! As always let me know if you have any questions, comments, feedback, suggestions, etc!

Thanks again and see you next time!

Update

It appears that the <dialog> element does not behave as intended on iOS. At least not on mobile iOS. I am going to do some further digging and update this article with the relevant information as soon as possible!


This content originally appeared on DEV Community and was authored by James Cox


Print Share Comment Cite Upload Translate Updates
APA

James Cox | Sciencx (2021-05-17T19:02:24+00:00) TIL – HTML Dialog Element. Retrieved from https://www.scien.cx/2021/05/17/til-html-dialog-element/

MLA
" » TIL – HTML Dialog Element." James Cox | Sciencx - Monday May 17, 2021, https://www.scien.cx/2021/05/17/til-html-dialog-element/
HARVARD
James Cox | Sciencx Monday May 17, 2021 » TIL – HTML Dialog Element., viewed ,<https://www.scien.cx/2021/05/17/til-html-dialog-element/>
VANCOUVER
James Cox | Sciencx - » TIL – HTML Dialog Element. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/17/til-html-dialog-element/
CHICAGO
" » TIL – HTML Dialog Element." James Cox | Sciencx - Accessed . https://www.scien.cx/2021/05/17/til-html-dialog-element/
IEEE
" » TIL – HTML Dialog Element." James Cox | Sciencx [Online]. Available: https://www.scien.cx/2021/05/17/til-html-dialog-element/. [Accessed: ]
rf:citation
» TIL – HTML Dialog Element | James Cox | Sciencx | https://www.scien.cx/2021/05/17/til-html-dialog-element/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.