Modals & lightbox
Overlays sit above page content with a scrim (and optional blur). The modal pattern is for decisions, forms, and confirmations; the lightbox pattern is for enlarged stills (editorial, product, evidence).
CSS handles layout, type, and motion — you still need a small amount of JavaScript to toggle hidden, trap focus, lock body scroll, and close on Escape / backdrop click.
Modal dialog
Root: .sermona-modal (typically role="dialog" + aria-modal="true" + aria-labelledby pointing at .sermona-modal__title).
Children:
button.sermona-modal__backdropor clickablediv— optional; many teams attach click-outside on the backdrop element witharia-hidden="true"if it is purely visual. If the backdrop is a button, label it “Close” or usearia-labeland match the dismiss action..sermona-modal__panel— scrollable card surface..sermona-modal__headerwith.sermona-modal__titleand.sermona-close-btn..sermona-modal__body— primary message..sermona-modal__footer—.sermona-btnactions (primary + secondary).
| Modifier | Use |
|---|---|
.sermona-modal--wide / --narrow | Wider confirmation vs compact destructive confirm. |
.sermona-modal--blur | Backdrop blur when prefers-reduced-transparency: no-preference. |
.sermona-modal--demo | Docs only: position: relative so the composition renders inside the page. Remove in production. |
Static preview (not focus-trapped — do not copy role="dialog" from this embedded demo without wiring behavior):
Save changes?
You have unsold draft edits. Discard them or keep editing — one clear primary action.
Demo uses sermona-modal--demo + so nested controls don’t steal focus on this page.
Image lightbox
.sermona-lightbox — near-black .sermona-lightbox__backdrop, .sermona-lightbox__content wrapping img, optional .sermona-lightbox__caption, .sermona-lightbox__close with .sermona-close-btn (light-on-dark treatment is scoped).
Use a single img with a meaningful alt. The caption may repeat tone for context but should not replace alt for non-decorative images.
Full-width visual proof — pair with keyboard scroll lock and focus return in production.
Close control
.sermona-close-btn — 44×44px target, focus-visible ring. Use aria-label="Close" (or “Close dialog”) and hide the icon with aria-hidden="true".
Behavior checklist (implementation)
- Open — Remove
hidden, move focus to the first focusable control (often Close or primary action). - Close — Restore focus to the opener; set
hiddenagain. - Escape — Close modal / lightbox.
- Scroll — Set
overflow: hiddenondocument.body(orpadding-inlinetrick) while open. - Tab — Keep focus cycle inside the overlay (first/last focusable handling).
- Reduced transparency — Blur on
.sermona-modal--bluris omitted when the user prefers reduced transparency.
See also
- Forms, buttons & CTAs — inputs and actions inside dialogs
- Voice & copy — confirmation and error copy
- Ecommerce patterns — product imagery workflows