Overlays
Modals, sheets, popovers and tooltips — everything that floats above
the page. Built on the native <dialog> element and
the Popover API, so focus trapping, Esc-to-close and top-layer
stacking come from the platform. Glass materials, dimmed scrims and
spring motion come from the tokens.
Modal
A <dialog class="b-modal"> opened with
showModal(). Any trigger with
data-b-dialog="#id" opens it; anything inside carrying
data-b-dialog-close closes it — no bespoke JS. Sizes:
.b-modal--sm, the 28rem default,
.b-modal--lg and .b-modal--xl. Add
.b-modal--glass for a translucent material that blurs
the content behind it.
showModal()
traps focus inside the dialog, makes the rest of the page inert, and
returns focus to the trigger on close — for free. Wire
aria-labelledby to the .b-modal__title id
so the dialog announces its purpose when it opens.Dialog vs Modal
One element, two behaviours. <dialog> opened with
showModal() is modal: it sits in the browser's
top layer, renders a ::backdrop scrim, and blocks the
page behind it. The same element opened with show() is a
non-modal dialog — an inline panel the user can ignore, with
no backdrop, no focus trap and no Esc handling. Barua styles both
from the same .b-modal class.
Reach for non-modal dialogs for ambient panels like a find bar or a picture-in-picture card; reach for modal when the flow genuinely cannot continue without an answer. If the user could reasonably keep working, it should not be modal.
Alert Dialog
A compact, centered confirmation in the iOS style: title,
one-sentence description, then full-width stacked actions separated
by hairlines. Mark the destructive choice with
.is-destructive and the preferred one with
.is-primary. Add
.b-alert-dialog__actions--row for the two-button
side-by-side arrangement, shown statically below with
show()-style inline rendering.
Row actions
aria-labelledby at the title and
aria-describedby at the description so both are spoken
on open. Esc closes the dialog natively and barua.js also closes any
open dialog when the backdrop is clicked — for irreversible actions,
make sure the default (Enter/first-focused) button is the safe one,
never the destructive one..is-destructive.Action Sheet
SwiftUI's confirmationDialog: a bottom-anchored glass
stack of choices with a separate Cancel group. Destructive choices
take .is-destructive. Built on native
<dialog> like every Barua overlay.
Sheet
A full-height panel that springs in from the trailing edge — the
macOS/iPadOS inspector pattern. It is still a
<dialog>, so it gets the scrim, focus trap and Esc
handling of a modal while reading as a side panel.
Bottom Sheet
Slides up from the bottom edge on a thick glass material, with a grabber affordance and safe-area padding. This is the preferred modal surface on mobile — thumb-reachable, dismissible, and familiar from every iOS share sheet.
aria-hidden="true" and always provide a real
button (or Esc) to dismiss; barua.js additionally closes the sheet
when the scrim above it is tapped. Because it is a modal dialog,
focus stays inside until it closes and then returns to the
trigger.Sheet Detents
SwiftUI's presentationDetents for the bottom sheet:
.b-bottom-sheet--medium caps the sheet at half the
viewport, --large at 92%. The default remains
content-sized up to 85%.
Popover
A light glass card for transient detail, built on the native Popover
API: popovers open centered in the viewport by default — add
.b-popover--anchored (or .b-menu--anchored)
only when you position one against its trigger yourself. Point
popovertarget at the popover's id and the
browser handles toggling, light-dismiss and Esc — zero JS. Where you
need guaranteed positioning without anchor support, wrap trigger and
card in .b-popover-anchor to pin the card under its
anchor (shown statically below).
Anchored fallback
Arrowed popover
Apple popovers point at what spawned them. Add
.b-popover--arrow-bottom (popover below its anchor,
caret on top), --arrow-top, --arrow-start
or --arrow-end — the caret inherits the glass
background and hairline.
Popover card
A structured popover for richer content — __header,
__body and a __footer action row, straight
from the Apple popover anatomy. Combine with any arrow direction.
Tooltip
CSS-only. Add .b-tooltip-host and a
data-tooltip label to any button or link; the tip fades
in above after a 350ms delay so it never flickers during casual
mouse travel. Use .b-tooltip-host--bottom when the
control sits near the top of the viewport.
:focus-visible, so keyboard users get the same hint.
They are supplementary — an icon-only control still needs its own
aria-label, and the tooltip must never carry
information available nowhere else.Hover Card
A richer preview that appears when hovering or focusing a reference
to a person or object — GitHub-style. Wrap the link in
.b-hover-card-host; the card fades in below after a
250ms delay and stays while hovered.
Platform team
Nairobi · joined 2021
412 threads · 38 shared labels
Dropdown
Dropdowns belong to the menu family documented in
Navigation: a zero-JS
<details class="b-dropdown"> disclosure holding a
.b-menu. One compact demo here for completeness.
Sort by
Lightbox
A borderless <dialog> that centers media over a
near-black blurred backdrop, with a floating close control pinned to
the top corner. Drop an <img> straight in — a
gradient placeholder stands in for one here.
File preview (Quick Look)
The same lightbox is how a file browser previews what you selected.
An image drops straight in; anything the browser renders itself — a
PDF, plain text — goes in a .b-lightbox__frame; and a
format with no preview shows .b-lightbox__empty: its
glyph, its name, and the way to get it. Every case carries the same
.b-lightbox__caption and
.b-lightbox__actions, so one keyboard escape and one
close control serve all three.
Fullscreen Overlay
Takes over the entire viewport for immersive tasks — composing, onboarding, distraction-free reading. A top bar keeps the exit visible at all times; the body scrolls independently beneath it.