Popover
A surface-tier panel anchored to a trigger, holding rich content.
Basic
A plain popover is a .popover__title over a .popover__body. Adding a .popover__header turns it into a panel: the root padding drops so header and footer dividers run edge to edge, and each part owns its padding. Give the .popover an id + data-stisla-popover, point a data-stisla-popover-trigger="id" button at it, and the @stisla/vanilla layer positions it with Floating UI, traps focus, and closes on outside click or ESC. The arrow is injected automatically, pointing back at the trigger. The demos below are live.
Keyboard
Hover-trigger popovers open on focus too, so keyboard users get the same affordance as hover users. Focus is not trapped, so Tab can leave the panel naturally. Pointer down outside the popover also dismisses.
- Enter / Space: open the popover when the trigger is focused (click-trigger mode)
- Escape: close the popover and return focus to the trigger
- Tab: move focus through the panel and out the other side
With a close chip
Drop in .popover__close for a corner dismiss affordance; the title clears it automatically.
Placements
data-stisla-popover-placement picks the resting side. Floating UI flips automatically when the chosen side would overflow the viewport.
Hover trigger
Add data-stisla-popover-trigger-mode="hover focus" to open on hover and keyboard focus. The 100ms close delay bridges the cursor from the trigger into the popover so it stays open while you read it.
Rich content
Author the body with whatever markup the popover needs. Paragraphs, links, buttons, and form bits all work. There's no string-content opt-in.
Panel
A .popover__header holds the title with a trailing .popover__action, a list sits in the body, and a .popover__footer closes it out. Add .popover--menu when the body is a list of rows so each .media row carries its own hover and the panel reads like a menu. Each row's leading slot takes an icon box or an avatar.
Imperative
Reach a marked popover via Stisla.get(document.getElementById('id')) and call Stisla.Popover.getOrCreate(el).open() when you need to drive it from script without a click trigger.
Events
Four events fire on the .popover root. The opening and closing events are cancelable.
stisla:popover:opening fires before the panel mounts. Call preventDefault() to abort.
stisla:popover:opened fires once the panel is positioned and visible.
stisla:popover:closing fires before the panel dismisses. Call preventDefault() to keep it open.
stisla:popover:closed fires once the panel is fully hidden and focus has returned to the trigger.
Customization
These variables retune the panel. Override on the root or any wrapper.
| Variable | Use |
|---|---|
--popover-z-index | Overlay stacking order |
--popover-min-width / -max-width | Panel width bounds |
--popover-padding-block / -padding-inline | Root padding (plain popover only; a panel drops it) |
--popover-color / -bg / -border-color | Panel text, fill, and rim |
--popover-radius / -shadow | Panel corner radius and elevation |
--popover-title-color / -font-size / -font-weight | Title type |
--popover-body-color / -font-size / -line-height | Body type (muted by default) |
--popover-header-gap / -header-padding-block / -header-padding-inline | Header row layout |
--popover-footer-padding-block / -footer-padding-inline | Footer padding |
--popover-close-size / -close-color / -close-bg-hover | Close chip size and paint |
--popover-arrow-size | Caret square size |
--popover-transition-duration | Fade and slide timing; zeroed under reduced-motion |