Popover

Anchored content that opens near its trigger.

v1.0.0·Updated Jul 8, 2026 · 10:45
Live Demo — Fully Interactive
Opens next to its trigger · below
Configuration
Placement
Header
Footer
Title
Filter by status
ResetApply
<Popover placement="bottom" title="Filter by status" actions={["Reset", "Apply"]} />
Behavior — The Engineering Contract
Props
PropTypeDefaultDescription
openbooleanfalseControlled visibility (or uncontrolled via trigger)
onOpenChange(open) => voidFires on trigger, outside click, or Escape
placementbottom · top · rightbottomSide the panel opens toward
triggerReactNodeThe anchoring element; gets aria-expanded
titlestringOptional header label
dismissOnOutsidebooleantrueClick outside closes; the page stays live
Events & keyboard
TriggerResult
Click triggerToggles open; a second click closes
Click outsideCloses; unlike a modal, no scrim blocks the page
EscapeCloses and returns focus to the trigger
TabMoves through the panel, then out — focus is not trapped

A popover is non-blocking: it never dims the page and never traps focus. If the content is a list of actions, that is a menu; if a single word of help, a tooltip; if the choice must block, a modal.

Anatomy
Filter1
2345
Filter by status
Free-form content.
Apply
1AnchorThe trigger element. The panel positions relative to it and inherits its aria-expanded.
2ArrowA rotated square that points back to the anchor, so the connection is never in doubt.
3HeaderOptional title, and a close button when the body is substantial.
4BodyFree-form: a filter set, a compact form, or a rich card.
5FooterOptional right-aligned actions to commit or reset the panel.
Do's and Don'ts
✓ Do
Filter · date range · rich card

Use a popover for contextual content that shouldn't block the page — filters, pickers, previews.

✕ Don't
Delete account? · in a popover

Don't confirm the irreversible in a popover. A stray outside click dismisses it — use a modal.

✓ Do
Points to its trigger.

Keep the arrow. It ties the panel to its anchor, so origin is obvious at a glance.

✕ Don't
Popover opening another popover

Don't nest popovers. Layers of floating panels lose the anchor and the user with it.

In context: Examples
A · Filter set
Status

Faceted filters live in a popover so results update without leaving the view.

B · A quick form
Rename
Homepage
Save

Inline edits — one or two fields — commit right where the trigger sits.

C · A rich card
Subin KMaintainer

Hover-card previews — a profile, a link unfurl — belong in a light, dismissable popover.

Measurements & Tokens
TokenValueRole
--pop-w260pxDefault panel width
--pop-bg#141519Panel surface (arrow inherits it)
--pop-border#262A30Panel and arrow hairline
--pop-radius12pxCorner radius
--pop-shadow0 18px 48px rgba(0,0,0,.55)Floating elevation
--pop-arrow10px, rotate 45°Square that points to the anchor
--pop-offset10pxGap between anchor and panel
--pop-ease0.18s easeFade + lift on open
Code
<div class="o-pop-anchor">
  <button class="o-btn o-btn--primary" aria-expanded="true" aria-haspopup="dialog">
    Filter
  </button>
  <div class="o-pop o-pop--bottom is-open" role="dialog">
    <span class="o-pop__arrow"></span>
    <div class="o-pop__head">Filter by status</div>
    <div class="o-pop__body"><!-- checkboxes --></div>
    <div class="o-pop__foot">
      <button class="o-btn o-btn--quiet">Reset</button>
      <button class="o-btn o-btn--primary">Apply</button>
    </div>
  </div>
</div>