<h1>Invoker commands!</h1>
<p>Using the commandfor on a button to trigger a dialog element</p>
<button commandfor="my-modal" command="show-modal">Invoke dialog</button>
<dialog id="my-modal">
  <header>
    <h2>Well hello there!</h2>
    <button class="btn btn--clean" commandfor="my-modal" command="close">
      <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-hidden="true">
        <path stroke-linecap="round" stroke-linejoin="round" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
      <span class="sr-only"></span>
    </button>
  </header>
  <main>
    <p>I am a lovely dialog with HTML, using invoker commands, currently available in canary</p>
  </main>
  <footer>
    <button class="outline" commandfor="my-modal" command="close">
      close
    </button>
  </footer>

</dialog>
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wdth@75..100&family=Oswald:wght@600&display=swap");

body:has(dialog[open]) {
  overflow: hidden;
}

@layer dialog.content {
  dialog {
    width: 100%;
    max-width: 600px;
    padding: 0;
    background: #fff;
    border-radius: 8px;
    border: 1px solid #dedede;
    box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px,
      rgba(0, 0, 0, 0.22) 0px 15px 12px;
    opacity: 0;
    translate: 0 30%;
    transition-property: opacity, translate, overlay, display;
    transition-duration: 0.8s;
    transition-behavior: allow-discrete;
    &::backdrop {
      /* Loving that gradient.style example <3 */
      background-image: linear-gradient(
        133deg in oklab,
        oklch(70% 0.5 340) 0%,
        oklch(90% 0.5 200) 100%
      );
      opacity: 0;
      cursor: pointer;
      transition-property: opacity, translate, overlay;
      transition-duration: 1s;
      transition-behavior: allow-discrete;
    }
    &[open] {
      opacity: 1;
      translate: 0 0;
      &::backdrop {
        opacity: 0.8;
      }
    }
  }

  @starting-style {
    dialog[open]::backdrop {
      opacity: 0;
    }
    dialog[open] {
      opacity: 0;
      translate: 0 -30%;
    }
  }
}

@layer dialog.content {
  dialog header {
    position: sticky;
    top: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 24px;
    background: #fff;
    border-bottom: 1px solid rgba(238, 118, 116, 1);
    h2 {
      margin: 0;
    }
  }

  dialog footer {
    border-top: 1px solid rgba(238, 118, 116, 1);
  }

  dialog > * {
    padding: 24px;
  }

  dialog p:last-of-type {
    margin-bottom: 0;
  }
}

@layer buttons {
  button {
    --_color: var(--color, fuchsia);
    padding: 0.5rem 1.2rem;
    border-radius: 5px;
    font-family: "Open Sans", sans-serif;
    font-size: 1.3rem;
    cursor: pointer;
    background: var(--_color);
    border: 2px solid var(--_color);
    color: white;
    transition: background 0.3s ease-out, color 0.3s ease-out,
      border-color 0.3s ease-out;
    box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
      rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
  }

  button.outline {
    background: transparent;
    color: var(--_color);
    box-shadow: none;
  }

  button:is(:hover, :focus) {
    --color: var(--hoverColor, deeppink);
  }
  .btn--clean {
    background: transparent;
    padding: 0;
    border: 0;
    color: inherit;
    box-shadow: none;
    &:is(:hover, :active, :focus) {
      color: darkviolet;
    }
  }
}

@layer base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    margin: 0;
    padding: 0;
    font-family: "Open Sans", sans-serif;
    font-size: 1.3rem;
    line-height: 1.6;
    min-block-size: 100dvb;
    display: flex;
    background: #474056;
    color: #fff;
  }

  h1,
  h2 {
    font-family: "Oswald", sans-serif;
    font-weight: 600;
    font-size: 4rem;
    margin-block-end: 1rem;
    text-shadow: -1px -1px 1px rgba(255, 255, 255, 0.2),
      1px 1px 1px rgba(0, 0, 0, 0.6);
  }

  h2 {
    font-size: 2rem;
    margin: 0;
  }

  p {
    margin-block-start: 0;
  }

  .sr-only {
    clip: rect(1px, 1px, 1px, 1px);
    clip-path: inset(50%);
    height: 1px;
    width: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
  }

  svg {
    width: 1.4rem;
    color: inherit;
  }
}
const dialogs = document.querySelectorAll("dialog");

dialogs.forEach(function (el) {
  el.addEventListener("click", ({ target: dialog }) => {
    if (dialog.nodeName === "DIALOG") {
      dialog.close("dismiss");
    }
  });
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.