Skip to content

Popover

hc-popover styles the native popover attribute. The browser handles open/close, top-layer rendering, light-dismiss, and Escape-to-close — no JavaScript required.

A short, focused message. The browser closes me on Escape or by clicking outside.

The popover attribute defaults to popover="auto", which means:

  • Light-dismiss on outside click.
  • Escape-to-close.
  • Only one auto popover is open at a time.

For a popover that ignores light-dismiss, use popover="manual" and close it yourself with element.hidePopover().

The basic light-dismiss popover above works from the native Popover API alone. The directional placement and htmx auto-close features below need behaviors — install the ones you use once at startup:

import { installPopover, installClosePopover } from '@hypermedia-components/core';
installPopover(); // data-side / data-align anchoring + aria sync
installClosePopover(); // close on a successful htmx request (optional)

The zero-config @hypermedia-components/core/behaviors entry installs both automatically.

A bare popover is positioned by the browser (centred in the top layer). To anchor it to its trigger with a side and alignment, add data-side (top / right / bottom / left) and optionally data-align (start / center / end, default center). installPopover() wires the anchoring and keeps aria-expanded / aria-controls on the trigger in sync. Add data-arrow for a small pointer.

Opens to the inline-end, top-aligned.

Placement uses CSS Anchor Positioning (position-area) where supported and position-try-fallbacks to flip at the viewport edge. The same attributes drive a JS fallback (getBoundingClientRect) for engines without it, so both paths place the popover identically. The shared mechanics — both paths, the arrow, and the --hc-anchored-* knobs — are documented in Fundamentals → Anchored positioning.

A popover can host an htmx-driven form. To close the popover after a successful request, add the data-hc-close-popover-on-success attribute and install the installClosePopover() behavior (bundled in @hypermedia-components/core/behaviors).

<form
class="hc-form"
data-hx-get="/items"
data-hx-target="#results"
data-hc-close-popover-on-success>
</form>

The behavior listens for htmx:afterRequest, checks for success, and calls closest('[popover]').hidePopover().

  • A popover is not automatically a menu. Setting role="menu" and providing arrow-key navigation are separate concerns documented elsewhere.
  • The trigger (the element with popovertarget) gets focus back when the popover closes — this is browser behavior.
  • For tooltip-like popovers triggered by hover or focus, use the [popovertargetaction="show"] attribute family or a custom hover handler. Hover-only tooltips are not accessible to keyboard users by themselves.
  • The popover’s accessible name comes from its content; if the popover has no visible title, add aria-label.
Token pathPurpose
popover.bg / -fg / -borderSurface colors.
popover.radiusBorder radius.
popover.paddingInner padding.
popover.min-width / -max-widthSize bounds.
Show the generated CSS variables
--hc-popover-bg | -fg | -border
--hc-popover-radius | -padding
--hc-popover-min-width | -max-width