Use this HTML structure:
<dialog>
<form method="dialog">
<button type="submit">Close</button>
</form>
</dialog>
Copy this CSS:
dialog {
/* Reset styles */
border: none;
padding: 0;
color: inherit;
max-width: unset;
max-height: unset;
/* Set styles to mimic open state for closing animation */
display: block;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
user-select: none;
/* Dialog styles (feel free to change) */
background-color: rgba(0, 0, 0, 0.8);
/* Closing animation */
opacity: 0;
transition: all 0.5s;
}
dialog[open] {
/* Opening animation */
visibility: visible;
opacity: 1;
pointer-events: unset;
user-select: text;
}
dialog::backdrop {
/* Reset style */
background: none;
}
form {
/* Closing animation */
transform: scale(0.9);
transition: transform 0.5s;
}
dialog[open] form {
/* Opening animation */
transform: none;
}
Open the dialog with JavaScript:
dialog.showModal()
Allow the user to click the greyed area to close:
// Close modal when backdrop clicked dialog.addEventListener('click', e => { if (e.target === e.currentTarget) { e.currentTarget.close() } })
dialog:-internal-dialog-in-top-layer {
position: fixed;
inset-block-start: 0px;
inset-block-end: 0px;
max-width: calc((100% - 6px) - 2em);
max-height: calc((100% - 6px) - 2em);
user-select: text;
visibility: visible;
overflow: auto;
}
Setting max-width and max-height to
unset while the dialog is open (dialog:modal)
seems to work. However, in Chrome, as the dialog is transitioning
closed, the margin appears. It's a very glitchy because the margin is
left over from a past rule, and it disappears when the element is
modified again.