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.