Modal
v1.0.0Modals display focused content or actions in a dialog above the current page.
Default
Use .modal on a native dialog element and open it with JavaScript.
<button class="btn btn-primary btn-solid" type="button" data-modal-target="#defaultModal">Open modal</button>
<dialog class="modal" id="defaultModal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Modal title</h3>
<button class="modal-close icon-btn icon-btn-text" type="button" data-modal-close aria-label="Close modal">
×
</button>
</div>
<div class="modal-body">
<p class="mb-0">This is a native dialog styled as a modal.</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary btn-text" type="button" data-modal-close>Cancel</button>
<button class="btn btn-primary btn-solid" type="button">Confirm</button>
</div>
</div>
</dialog>
Simple modal
The modal structure can be reduced when no footer actions are needed.
<dialog class="modal" id="simpleModal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Simple modal</h3>
<button class="modal-close icon-btn icon-btn-text" type="button" data-modal-close aria-label="Close modal">
×
</button>
</div>
<div class="modal-body">
<p class="mb-0">This modal only contains a header and body.</p>
</div>
</div>
</dialog>
Long content
The modal body becomes scrollable when the content is taller than the available viewport height.
<dialog class="modal" id="longContentModal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Long content</h3>
<button class="modal-close icon-btn icon-btn-text" type="button" data-modal-close aria-label="Close modal">
×
</button>
</div>
<div class="modal-body">
<p>Long content...</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary btn-text" type="button" data-modal-close>Close</button>
</div>
</div>
</dialog>
Sizes
Use .modal-sm, .modal-lg or .modal-xl to change the modal width.
<dialog class="modal modal-sm" id="smallModal">...</dialog>
<dialog class="modal modal-lg" id="largeModal">...</dialog>
<dialog class="modal modal-xl" id="extraLargeModal">...</dialog>
Confirmation modal
Modals are useful for focused confirmation flows.
<button class="btn btn-error btn-solid" type="button" data-modal-target="#confirmationModal">Delete item</button>
<dialog class="modal" id="confirmationModal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Delete item?</h3>
<button class="modal-close icon-btn icon-btn-text" type="button" data-modal-close aria-label="Close modal">
×
</button>
</div>
<div class="modal-body">
<p class="mb-0">This action cannot be undone. Please confirm that you want to delete this item.</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary btn-text" type="button" data-modal-close>Cancel</button>
<button class="btn btn-error btn-solid" type="button" data-modal-close>Delete</button>
</div>
</div>
</dialog>
JavaScript
Use showModal() and close() to control native dialog elements.
export function initModals(): void {
document.querySelectorAll<HTMLElement>('[data-modal-target]').forEach(trigger => {
const isInitialized: boolean = trigger.dataset.modalInitialized === 'true';
if (!isInitialized) {
trigger.dataset.modalInitialized = 'true';
trigger.addEventListener('click', () => {
const targetSelector: string | undefined = trigger.dataset.modalTarget;
const modal: HTMLDialogElement | null = targetSelector
? document.querySelector<HTMLDialogElement>(targetSelector)
: null;
if (modal && !modal.open) {
modal.showModal();
}
});
}
});
document.querySelectorAll<HTMLDialogElement>('.modal').forEach(modal => {
const isInitialized: boolean = modal.dataset.modalInitialized === 'true';
if (!isInitialized) {
modal.dataset.modalInitialized = 'true';
modal.querySelectorAll<HTMLElement>('[data-modal-close]').forEach(closeButton => {
closeButton.addEventListener('click', () => {
modal.close();
});
});
modal.addEventListener('click', event => {
const target: EventTarget | null = event.target;
if (target === modal) {
modal.close();
}
});
}
});
}