<div class="section">
<h2>Modal Example</h2>
<button class="button modal-trigger" aria-controls="modal">Open Modal</button>
<dialog id="modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>Modal Title</h2>
<button class="modal-dismiss" title="Close modal" data-modal-dismiss>
✕
<span class="sr-only">Close modal</span>
</button>
</div>
<div class="modal-body">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum, obcaecati ut modi cumque corporis ad asperiores rerum rem aliquam porro vitae quibusdam similique incidunt laborum quia odio, labore perferendis saepe!</p>
</div>
<div class="modal-footer">
<p>This is the modal footer</p>
</div>
</div>
</dialog>
</div>
:root {
--color-accent: hsla(212, 100%, 45%, 1);
--color-background: hsla(0, 0%, 95%, 1);
--color-border: hsl(0, 0%, 90%);
}
.modal {
--_modal-min-height: 500px;
--_modal-max-width: min(520px, 100%);
--_modal-inset: 0;
--_modal-padding: 1rem;
--_modal-border-radius: 0.5rem;
margin: auto;
padding: 0;
border: 0;
background-color: transparent;
inset: var(--_modal-inset);
inline-size: 100%;
max-inline-size: var(--_modal-max-width);
animation: dialogFadeIn 300ms ease forwards;
}
.modal::backdrop {
background-color: rgba(0, 0, 0, 0.65);
}
.modal-header,
.modal-footer {
display: flex;
align-items: center;
justify-content: space-between;
background-color: var(--color-background);
padding: var(--_modal-padding);
}
.modal-header {
border-block-end: 1px solid var(--color-border);
border-radius: var(--_modal-border-radius) var(--_modal-border-radius) 0 0;
}
.modal-body {
background-color: var(--color-background);
padding: var(--_modal-padding);
}
.modal-footer {
border-block-start: 1px solid var(--color-border);
border-radius: 0 0 var(--_modal-border-radius) var(--_modal-border-radius);
}
/*
* Basic reset and styles
*/
body {
font-family: sans-serif;
min-block-size: 100vh;
}
.section {
display: grid;
place-content: center;
block-size: 100vh;
}
.section > h2 {
margin-block-end: 0.625rem;
}
button {
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 0.325rem;
color: var(--color-accent);
background-color: transparent;
border: 0;
}
.button {
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.5rem 0.625rem;
border-radius: 8px;
color: #fff;
background-color: var(--color-accent);
border: 1px solid var(--color-accent);
}
.sr-only {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
inline-size: 1px;
}
const modalTriggers = document.querySelectorAll(".modal-trigger");
modalTriggers.forEach(handleShow);
function handleShow(trigger) {
trigger.addEventListener("click", () => {
const dialogId = trigger.getAttribute("aria-controls");
const dialog = document.getElementById(dialogId);
const modalDismiss = dialog.querySelectorAll("[data-modal-dismiss]");
if (!dialog) return;
dialog.showModal();
modalDismiss.forEach((dismiss) => {
dismiss.addEventListener("click", closeModal);
});
dialog.addEventListener("click", closeDialogOnClickOutside);
function closeModal(e) {
dialog.close();
modalDismiss.forEach((dismiss) => {
dismiss.removeEventListener("click", closeModal);
});
dialog.removeEventListener("click", closeDialogOnClickOutside);
document.removeEventListener("click", closeDialogOnClickOutside);
}
function closeDialogOnClickOutside(e) {
e.target === dialog && closeModal();
}
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.