Modal â Vanilla
Modal dialog with vanilla HTML + JS. Same BEM and sizes as Astro/Svelte. Ensure Rizzo CSS is loaded.
Modal
Dialog with overlay, focus trap, and optional sizes (sm, md, lg). Same structure as Astro and Svelte.
Add this component
The command below includes <strong>Modal</strong>ârun it in your project directory to install this component (and the CSS if needed). No prompts.
Choose your package manager â click a tab to select, then copy the command.
Modal sizes
Small (24rem), medium (32rem), large (48rem). Click to open:
Standard example
Click the button below to open a standard modal dialog:
HTML
Use modal__overlay (sibling) and modal with modal__header, modal__body, modal__footer. Size: modal--sm, modal--md, modal--lg.
<button type="button" class="btn btn-primary" id="open-modal-btn">Open Example Modal</button>
<!-- Use .modal-root so overlay stacks behind the modal. Overlay id: <modalId>-overlay. -->
<div class="modal-root">
<div class="modal__overlay" id="demo-overlay" aria-hidden="true"></div>
<div class="modal modal--md" id="demo-modal" role="dialog" aria-modal="true" aria-labelledby="demo-modal-title" aria-hidden="true">
<div class="modal__header">
<h2 class="modal__title" id="demo-modal-title">Example Modal</h2>
<button type="button" class="modal__close" aria-label="Close modal">Ã</button>
</div>
<div class="modal__body">
<p>This is an example modal dialog. It demonstrates:</p>
<ul>
<li>Focus trapping â Tab cycles within the modal</li>
<li>Keyboard navigation â Escape key closes the modal</li>
<li>Backdrop overlay with blur effect</li>
<li>Theme-aware styling</li>
</ul>
</div>
<div class="modal__footer">
<button type="button" class="btn">Cancel</button>
<button type="button" class="btn btn-primary">Confirm</button>
</div>
</div>
</div> JavaScript
(function() {
var openBtn = document.getElementById('open-modal-btn');
var overlay = document.getElementById('demo-overlay');
var modal = document.getElementById('demo-modal');
if (!openBtn || !overlay || !modal) return;
function openModal() {
overlay.setAttribute('aria-hidden', 'false');
modal.setAttribute('aria-hidden', 'false');
document.body.style.overflow = 'hidden';
}
function closeModal() {
overlay.setAttribute('aria-hidden', 'true');
modal.setAttribute('aria-hidden', 'true');
document.body.style.overflow = '';
}
openBtn.addEventListener('click', openModal);
overlay.addEventListener('click', closeModal);
modal.querySelector('.modal__close').addEventListener('click', closeModal);
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && modal.getAttribute('aria-hidden') === 'false') closeModal();
});
})();