Skip to content

Instantly share code, notes, and snippets.

@coder0107git
Last active May 13, 2025 00:58
Show Gist options
  • Save coder0107git/49c7d32ccee3731a52488c76d35906e1 to your computer and use it in GitHub Desktop.
Save coder0107git/49c7d32ccee3731a52488c76d35906e1 to your computer and use it in GitHub Desktop.
Modal dialog without any javascript
dialog[popover]:not([open]) {
box-sizing: border-box;
/*
* Readd Chrome UA styles on popover dialogs since they
* are overwritten when marked as a popover. An explanation
* I found useful was [this](https://youtu.be/yZT9906ZCLU?t=543)
* video, but be forewarned, the padding part does not apply
* to `[popover]` dialogs.
*/
max-width: calc(100% - 2em - 6px);
max-height: calc(100% - 2em - 6px);
/*
* Just for some extra sanity, readding the Chrome UA
* padding from popover elements. This differs from the
* default for dialogs (0.25em instead of 1em);
*/
--padding: 0.25em;
padding: var(--padding);
& [aria-label="close"] {
position: absolute;
/*
* Since padding doesn't work on elements pulled out of
* the flow, right is needed instead.
*/
right: var(--padding);
/* Make the close button handle RTL languages. Needs some improvement. */
&:where(&:dir(rtl), [dir=rtl]:has(&)) {
right: revert;
left: var(--padding);
}
}
&::backdrop {
background: rgba(0, 0, 0, 0.1);
}
/* Disable elements not in the dialog when the popover is active */
*:has(&:popover-open) {
cursor: default;
/* Keep text selection and pointer events from escaping the popover dialog */
pointer-events: none;
user-select: none;
}
&:popover-open {
pointer-events: all;
cursor: auto;
/* Keep text selection from escaping the popover dialog */
user-select: text;
/*
* Not currently implemented by any major browser but here anyways
* incase it ever gets implemented.
*/
user-select: contain;
}
}
pre {
overflow: auto;
margin: 0;
}
<p>WARNING: Tab can escape the modal. Only use if you absolutely can't justify using JS and you are fine with tab focus not trapping.</p>
<p>Please use <a href="https://web.dev/learn/html/dialog#modal_dialogs"><code>dialog.showModal()</code></a> if you can instead.</p>
<hr />
<button popovertarget="my-dialog" popovertargetaction="toggle">
Open dialog
</button>
<dialog id="my-dialog" popover>
<button
aria-label="close"
title="close"
popovertarget="my-dialog"
popovertargetaction="hide"
>&times;</button>
<pre>
S
A
LUT
M
O N
D E
DONT
E SUIS
LA LAN
G U E É
L O Q U E N
TE QUESA
B O U C H E
O P A R I S
T I R E ET TIRERA
T O U JOURS
AUX A L
LEM ANDS - Apollinaire
</pre>
</dialog>
<hr/>
<h2>Random interactive elements</h2>
<p>Before opening the dialog, tab thru these interactive elements. Then
try again when the dialog is open.</p>
<p>When the dialog is open, are any of these normally interactive elements interactive?</p>
<p><a href="https://machinelearningworkshop.com" target="_blank">Machine Learning Workshop</a></p>
<p><label>Here is a useless input: <input></label></p>
<p>
<label>Here is a useless select:
<select name="yummy">
<option>Maple Syrup</option>
<option>Ice Cream</option>
<option>Bacon</option>
</select>
</label>
</p>
name: JS-less modal using <dialog popover>
@coder0107git
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment