Dialogs

Native HTML <dialog> elements with optional transition animation styles and light-dismiss.

Examples

The dialogs use a script and method from Fun with the dialog element by Mark Otto that uses data-attributes with unique IDs to provide the opening and closing functionality, but if required a form method="dialog" button can also be combined with the technique for closing dialogs containing form content.

Basic

Uses script for the opening and closing buttons.

Form method

Uses script for opening and form method button for closing.

Example HTML
<button data-dialog="#dialog">Basic</button>
<dialog id="dialog">
  <h2>Basic</h2>
  <p>Uses script for the opening and closing buttons.</p>
  <button class="close-dialog">Close</button>
</dialog>

<button data-dialog="#dialog-form">Form method</button>
<dialog id="dialog-form">
  <h2>Form method</h2>
  <p>Uses script for opening and form method button for closing.</p>
  <form method="dialog">
    <button>Close</button>
  </form>
</dialog>
Script
let toggler = document.querySelectorAll("[data-dialog]"),
  closers = document.querySelectorAll(".close-dialog");
toggler &&
  (toggler.forEach(function (e) {
    let l = e.getAttribute("data-dialog"),
      t = document.querySelectorAll(l);
    e.addEventListener("click", (e) => {
      t.forEach(function (e) {
        e.showModal();
      });
    });
  }),
  closers.forEach(function (e) {
    e.addEventListener("click", (l) => {
      e.closest("dialog").close();
    });
}));

Light-dismiss

Placed as the last child within the dialog the <div class="close-dialog"></div> is styled as a background element that uses the script closing functionality to enable clicking outside the dialog to close it.

Light-dismiss

Uses script for opening, closing and light-dismiss.

Form method

Uses script for opening and form method button for closing.

Example HTML
<button data-dialog="#dialog-light-dismiss">Basic light-dismiss</button>
<dialog id="dialog-light-dismiss">
  <h2>Light-dismiss</h2>
  <p>Uses script for opening, closing and light-dismiss.</p>
  <button class="close-dialog">Close</button>
  <div class="close-dialog"></div>
</dialog>

<button data-dialog="#dialog-form-light-dismiss">Form method light-dismiss</button>
<dialog id="dialog-form-light-dismiss">
  <h2>Form method</h2>
  <p>Uses script for opening and form method button for closing.</p>
  <form method="dialog">
    <button>Close</button>
  </form>
  <div class="close-dialog"></div>
</dialog>

Transition

The optional transition animation style can be customized inline using the CSS variable --dialog-transition.

Heading basic

The quick brown fox jumps over the lazy dog.

Heading basic

The quick brown fox jumps over the lazy dog.

Heading basic

The quick brown fox jumps over the lazy dog.

Examples HTML

The dialog animation is enabled for this website so the 'No transition' example uses the variable to remove the default .25s transition included to demonstrate default non-animated dialogs.

<button data-dialog="#default-transition">No transition</button>
<dialog id="default-transition" style="--dialog-transition: 0s;">
  <h2>Heading basic</h2>
  <p>The quick brown fox jumps over the lazy dog.</p>
  <button class="close-dialog">Close</button>
  <div class="close-dialog"></div>
</dialog>

<button data-dialog="#transition-enabled">Enabled (default .25s)</button>
<dialog id="transition-enabled">
  <h2>Heading basic</h2>
  <p>The quick brown fox jumps over the lazy dog.</p>
  <button class="close-dialog">Close</button>
  <div class="close-dialog"></div>
</dialog>

<button data-dialog="#transition-custom">Enabled (custom 1.5s)</button>
<dialog id="transition-custom" style="--dialog-transition: 1.5s;">
  <h2>Heading basic</h2>
  <p>The quick brown fox jumps over the lazy dog.</p>
  <button class="close-dialog">Close</button>
  <div class="close-dialog"></div>
</dialog>

Using the module

Add the sassmods.scss to your custom styles as below then include the Sass mixin(s) anywhere below.

custom.scss
@use "sassmods/scss/sassmods" as *;
@include dialogs-css;
@include dialogs-animation-css;

See customizing for information about using the Sass and CSS variables in the source code (see below) to customize the styles, and Sass variables (on the using SassMods page) for other ways to use the variables to create custom styles.

Source

_dialogs.scss
// ---------------------------------------------------------- 
// Dialogs
// ----------------------------------------------------------
$dialog-text-color:         var(--dialog-text) !default;
$dialog-margin-top:         var(--dialog-mt, 1rem) !default;
$dialog-padding-block:      var(--dialog-py, 0.75rem) !default;
$dialog-padding-inline:     var(--dialog-px, 1rem) !default;
$dialog-border-color:       var(--dialog-bd-color, color-mix(in srgb, CanvasText 12%, Canvas)) !default;
$dialog-radius:             var(--dialog-radius, 0.125em) !default;
$dialog-background-color:   var(--dialog-bg, Canvas) !default; 
$dialog-transition:         var(--dialog-transition, 0.25s) !default;
$dialog-backdrop:           color-mix(in srgb, black 50%, transparent) !default;

@mixin dialogs-css {

:where(dialog) {
  color: $dialog-text-color;
  block-size: fit-content;
  max-block-size: calc(100vh - 2rem);
  inline-size: calc((100% - 6px) - 2em);
  max-inline-size: var(--dialog-width, fit-content);
  margin-block-start: $dialog-margin-top;
  padding-block: $dialog-padding-block;
  padding-inline: $dialog-padding-inline;
  border: 1px solid $dialog-border-color;
  border-radius: $dialog-radius;
  background-color: $dialog-background-color; 
  overflow: auto;
  overscroll-behavior: contain; 
}

dialog div[class="close-dialog"] {
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  content: "";
}

dialog[open]::backdrop {
  background-color: $dialog-backdrop;
}

} // end dialogs-css

@mixin dialogs-animation-css {

@media screen and (prefers-reduced-motion: no-preference) {
  dialog[open] {
    transition: $dialog-transition;
    opacity: 1; 
  }
}

@starting-style {
  dialog[open] {
    opacity: 0;    
  }
}

}