Modal
Create accessible modals, with full keyboard and focus management.
The BLX Modal provides an accessible, CMS-friendly way to trigger dialog overlays, with support for responsive behaviour, scroll locking, and flexible pairing between triggers and popups.
Use a modal when you need to:
- reveal secondary information without navigating away
- show contextual content (e.g. team profiles, job details)
- conditionally expose content on smaller screens (tablet/mobile)
1. Add Script
Add this <script> inside the before </body> tag of your page or project.
<script defer src="https://cdn.jsdelivr.net/gh/codeandwander/blx@v1.0.5/packages/modal/index.js"></script>2. Add CSS
Add the CSSΒ to the <head> custom code of the project or inside your custom code component.
[blx-el="modal-popup"] {
display: none;
}
[blx-el="modal-popup"].is-open {
display: block;
}
/* if using scroll lock */
.blx-scroll-lock {
overflow: hidden;
}Is also recommended to have the modal as position fixed.
3. Add attributes
blx-el="trigger"- Defines the element that opens the modal.blx-el="modal-popup"- Defines the modal container.blx-el="modal-close"- Closes the modal. Any number of close elements can exist.
Pairing triggers and modals
BLX supports two pairing strategies, in order of priority.
modal-group (recommended)
Use when the trigger and modal live near each other in the DOM (e.g. CMS cards).
<div blx-el="modal-group">
<button blx-el="modal-trigger">
Open
</button>
<div blx-el="modal-popup">
<button blx-el="modal-close">Close</button>
// Modal content
</div>
</div>
- The outer wrapper groups triggers and modals together.
- Multiple modal groups can exist on the same page.
- This is the preferred and most robust approach.
blx-id (fallback / remote pairing)
Use when the trigger and modal are not close in the DOM. For example having the modal in the footer and trigger on the page.
<button blx-el="modal-trigger" blx-id="contact-form">
Open profile
</button>
<div blx-el="modal-popup" blx-id="contact-form">
<button blx-el="modal-close">Close</button>
// Modal content
</div>
- Matching
blx-idvalues pair the trigger and modal. - Useful for shared modals or distant layouts.
Behaviour control
blx-prop allows you to conditionally enable modal behaviour or add enhancements.
Multiple props can be combined in a single attribute:
blx-prop="tablet, scroll-lock"
Available props
This allows you to enable the modal only on tablet and/or mobile. For example if you want an element to behave as a sidebar on desktop and modal on smaller screens.
- β
tablet- Modal opens only at viewport widths β€ 991px. No modal functionality on desktop. - β
mobile- Modal opens only at viewport widths β€ 767px. No modal functionality on desktop or tablet. scroll-lock- Prevents background scrolling while the modal is open.
Where to place blx-prop
Props are resolved in the following order:
blx-el="modal-group"blx-el="modal-trigger"
First match wins. You can place the blx-prop on the modal-group or the modal-trigger depending on your setup.
Example (group-level props)
<div blx-el="modal-group" blx-prop="mobile, scroll-lock">
Example (trigger-level props β recommended default)
<button blx-el="modal-trigger" blx-prop="tablet">
Accessibility
BLX Modal is built to follow accessible dialog best practices when operating as a modal. If the blx-prop="tablet" or blx-prop="mobile" is present, it remaining unobtrusive on the higher breakpoints.
BLX Modal automatically:
- Assigns unique IDs to modal elements when missing
- Links triggers and modals using
aria-controls - Updates
aria-expandedon triggers to reflect open / closed state - Exposes correct dialog semantics in overlay mode only:
- Adds
role="dialog" - Adds
aria-modal="true" - Toggles
aria-hiddenappropriately
- Adds
- Supports keyboard activation of triggers (
Enter,Space) - Allows closing via
Esckey when in overlay mode - Traps keyboard focus within the modal while open
- Restores focus to the triggering element when the modal closes
Your responsibilities
To ensure full accessibility compliance, you should:
- Provide an accessible label for each modal using:
aria-labelledby(recommended), oraria-label(fallback)
- Avoid placing essential content only inside inline modals when overlay behaviour is disabled at certain breakpoints
Tip:Β Add blx-el="modal-close" to the background overlay to close when clicking outside.