A Pen by Matt Daniel Brown on CodePen.
Created
January 12, 2025 01:20
-
-
Save mattdanielbrown/2428e24f41ec21d0a0b8a59ade0a02a8 to your computer and use it in GitHub Desktop.
<dialog> types
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <dialog id="dialogDefault"> | |
| <form method="dialog"> | |
| <p>Hi, I'm the default dialog.</p> | |
| <button type="submit" value="ok">OK</button> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogError" role="alertdialog" class="classic error"> | |
| <header>⚠ Error!</header> | |
| <form method="dialog"> | |
| <p>This is an error message.</p> | |
| <footer> | |
| <button type="submit" value="close">Close</button> | |
| </footer> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogWait" class="classic wait"> | |
| <header>🕑 Please wait</header> | |
| <form method="dialog"> | |
| <progress indeterminate></progress> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogNotify" class="classic notify"> | |
| <header>ℹ Something happened!</header> | |
| <form method="dialog"> | |
| <p>Something happened that I need to tell you.</p> | |
| <footer> | |
| <button type="submit" value="ok">OK</button> | |
| </footer> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogConfirm" class="classic"> | |
| <header>☑ Please Confirm</header> | |
| <form method="dialog"> | |
| <p>The web is awesome right?</p> | |
| <footer> | |
| <button class="light" type="submit" value="yes">Yes</button> | |
| <button class="error" type="submit" value="no">No</button> | |
| </footer> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogTransition" class="classic animated"> | |
| <header>➥ I'm animated!</header> | |
| <form method="dialog"> | |
| <p>I don't use any keyframes either, I'm all CSS transitions.</p> | |
| <footer> | |
| <button class="light" type="submit" value="rad">Rad</button> | |
| </footer> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogDismiss" class="classic"> | |
| <header>Close me by clicking the backdrop</header> | |
| <form method="dialog"> | |
| <p>Some Javascript is listening for clicks and closing this dialog if it notices the backdrop was clicked.</p> | |
| <p>Note: Wanting light dismiss for a dialog tends to mean the UX you're after is a <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover">popover</a>.</p> | |
| </form> | |
| </dialog> | |
| <dialog id="dialogCustom" class="custom classic animated"> | |
| <header> | |
| <span>✏️ New User</span> | |
| <button onclick="dialogCustom.close('X')"> | |
| <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"> | |
| <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> | |
| </svg> | |
| </button> | |
| </header> | |
| <form method="dialog"> | |
| <div> | |
| <label for="uname">User Name</label> | |
| <input type="text"> | |
| </div> | |
| <footer> | |
| <button class="light" type="submit" value="create">Create</button> | |
| <button class="error" type="submit" value="cancel">Cancel</button> | |
| </footer> | |
| </form> | |
| </dialog> | |
| <button onclick="dialogDefault.showModal()">Default</button> | |
| <button onclick="dialogError.showModal()" class="error">Error</button> | |
| <button onclick="dialogWait.showModal(); fakeWait()" class="wait">Wait</button> | |
| <button onclick="dialogNotify.showModal()" class="light">Notify</button> | |
| <button onclick="dialogConfirm.showModal()" class="light">Confirm</button> | |
| <button onclick="dialogTransition.showModal()" class="dark">Transitions</button> | |
| <button onclick="dialogDismiss.showModal()" class="dark">Light Dismiss</button> | |
| <button onclick="dialogCustom.showModal()" class="custom">Custom</button> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function fakeWait() { | |
| setTimeout(() => { | |
| dialogWait.close('wait completed') | |
| }, 2000) | |
| } | |
| // light dismiss | |
| dialogDismiss.addEventListener('click', ({target:dialog}) => { | |
| if (dialog.nodeName === 'DIALOG') { | |
| dialog.close('dismiss') | |
| } | |
| }) | |
| // watch for closed dialogs | |
| // log the close value to know what button user's clicked | |
| document.querySelectorAll('dialog').forEach(dialog => { | |
| dialog.onclose = event => { | |
| console.log(event.target.returnValue) | |
| } | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* disables scrolling the page behind a dialog */ | |
| html:has(dialog[open]) { | |
| overflow: hidden; | |
| } | |
| @layer dialogs { | |
| dialog.classic { | |
| --_theme-color: CanvasText; | |
| --_on-theme-color: Canvas; | |
| border-color: var(--_theme-color); | |
| accent-color: var(--_theme-color); | |
| padding: 0; | |
| inline-size: clamp(25ch, 60ch, 80vw); | |
| border-radius: 10px; | |
| > header { | |
| display: flex; | |
| align-items: center; | |
| background: var(--_theme-color); | |
| color: var(--_on-theme-color); | |
| padding: .75rem 1rem; | |
| font-weight: bold; | |
| font-size: 1.25rem; | |
| } | |
| > form { | |
| padding: 1.25rem 1rem 1rem; | |
| > p { | |
| margin-block-start: 0; | |
| line-height: 1.5; | |
| &:last-child { | |
| margin-block-end: 0; | |
| } | |
| } | |
| } | |
| footer { | |
| display: flex; | |
| gap: 1ch; | |
| place-content: center end; | |
| margin-block-start: 2rem; | |
| padding-block-start: 1rem; | |
| border-block-start: 1px solid #aaa3; | |
| } | |
| } | |
| dialog.error { | |
| --_theme-color: red; | |
| --_on-theme-color: white; | |
| &::backdrop { | |
| background-color: hsl(from var(--_theme-color) h s 20% / 10%) | |
| } | |
| } | |
| dialog.wait { | |
| --_theme-color: Highlight; | |
| --_on-theme-color: HighlightText; | |
| progress { | |
| inline-size: 100%; | |
| } | |
| } | |
| /* enable transitions */ | |
| dialog.animated { | |
| &, &::backdrop { | |
| transition: | |
| display .3s allow-discrete, | |
| overlay .3s allow-discrete, | |
| opacity .3s, | |
| transform .3s; | |
| opacity: 0; | |
| transition-timing-function: ease-in-out; | |
| } | |
| /* ON STAGE */ | |
| &[open] { | |
| opacity: 1; | |
| &::backdrop { | |
| opacity: 0.8; | |
| } | |
| } | |
| /* OFF STAGE */ | |
| @starting-style { | |
| &[open], | |
| &[open]::backdrop { | |
| opacity: 0; | |
| } | |
| &[open] { | |
| transform: translateY(10px); | |
| } | |
| } | |
| &::backdrop { | |
| background-color: black; | |
| } | |
| } | |
| dialog.custom { | |
| --_theme-color: oklch(98% .02 200 / 50%); | |
| --_on-theme-color: oklch(30% .02 200); | |
| max-inline-size: 40ch; | |
| background: oklch(90% .02 200 / 25%); | |
| > header { | |
| display: flex; | |
| justify-content: space-between; | |
| > button { | |
| background: none; | |
| box-shadow: none; | |
| padding: 0; | |
| height: 2ch; | |
| width: 2ch; | |
| color: var(--_on-theme-color); | |
| } | |
| } | |
| > form > div { | |
| display: grid; | |
| gap: .5ch; | |
| } | |
| input { | |
| padding: 1ch 1lh; | |
| border-radius: 5px; | |
| background: oklch(90% .02 200 / 25%); | |
| color: var(--_on-theme-color); | |
| border: 1px solid oklch(90% .02 200 / 35%); | |
| } | |
| &::backdrop { | |
| background: radial-gradient(circle at center, hsl(220 50% 50% / 50%), hsl(220 50% 50% / 0%)); | |
| backdrop-filter: blur(25px); | |
| } | |
| &[open]::backdrop { | |
| opacity: 1; | |
| } | |
| } | |
| } | |
| @layer buttons { | |
| button { | |
| font-size: 1.25rem; | |
| padding-block: 1ch; | |
| padding-inline: 2ch; | |
| border-radius: 5px; | |
| border: 1px solid #0000; | |
| box-shadow: 0 2px 3px #0003; | |
| outline-offset: 5px; | |
| dialog footer & { | |
| font-size: 1rem; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| box-shadow: 0 2px 3px #000a; | |
| } | |
| } | |
| button.error { | |
| background: red; | |
| color: white; | |
| border-color: red; | |
| } | |
| button.wait { | |
| background: Highlight; | |
| color: HighlightText; | |
| border-color: Highlight; | |
| } | |
| button.light { | |
| background: white; | |
| color: #222; | |
| border-color: #eee; | |
| } | |
| button.dark { | |
| background: hsl(200 5% 15%); | |
| color: #fff; | |
| border-color: hsl(200 5% 20%); | |
| } | |
| dialog.custom { | |
| header button { | |
| padding: 0; | |
| inline-size: 2ch; | |
| block-size: 2ch; | |
| } | |
| button { | |
| box-shadow: 0 2px 3px #0003; | |
| } | |
| } | |
| } | |
| html { | |
| block-size: 100%; | |
| color-scheme: dark light; | |
| } | |
| body { | |
| min-block-size: 100%; | |
| font-family: system-ui, sans-serif; | |
| display: flex; | |
| flex-flow: row wrap; | |
| place-items: center; | |
| place-content: center; | |
| gap: 1rem; | |
| margin: 0; | |
| } | |
| p { | |
| text-wrap: pretty; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment