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-id values 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:

  1. blx-el="modal-group"
  2. 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-expanded on triggers to reflect open / closed state
  • Exposes correct dialog semantics in overlay mode only:
    • Adds role="dialog"
    • Adds aria-modal="true"
    • Toggles aria-hidden appropriately
  • Supports keyboard activation of triggers (Enter, Space)
  • Allows closing via Esc key 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), or
    • aria-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.