Components

Popover

An anchored popover panel built on the native Popover API and CSS anchor positioning.

UiPopover renders a floating panel using the browser's native Popover API (the popover attribute) positioned with CSS anchor positioning. A trigger toggles it by id, and the popover anchors to any element that declares a matching anchor-name.

For a ready-made user/account dropdown with a header and item list, use Popover Menu instead.

Add a popover

The trigger targets the popover by id (popovertarget) and declares the anchor (anchor-name); the popover positions against it via its anchor-name prop.

<template>
  <!-- Trigger: toggles the popover and acts as its anchor -->
  <UiButton
    text="Open"
    popovertarget="profile-popover"
    style="anchor-name: --profile"
  />

  <UiPopover
    id="profile-popover"
    anchor-name="--profile"
    position-block="bottom"
    position-inline="right"
    size="sm"
  >
    <template #header>
      <strong>Jane Doe</strong>
    </template>
    <template #body>
      <p>Product designer</p>
    </template>
    <template #footer>
      <UiButton
        variant="text"
        text="Close"
        popovertarget="profile-popover"
        popovertargetaction="hide"
      />
    </template>
  </UiPopover>
</template>

Position the panel

positionBlock controls the vertical side and positionInline the horizontal side:

<template>
  <UiPopover id="p1" anchor-name="--a1" position-block="top" position-inline="left" />
  <UiPopover id="p2" anchor-name="--a2" position-block="bottom" position-inline="right" size="lg" />
</template>

Props

PropTypeDefaultDescription
idstring—Unique id; the trigger targets it via popovertarget (required).
anchorNamestring—CSS anchor name to position against, e.g. --profile (required). The trigger must set anchor-name to the same value.
positionBlock'top' | 'bottom''top'Vertical placement relative to the anchor.
positionInline'left' | 'right''left'Horizontal placement relative to the anchor.
size'sm' | 'lg'—Popover size.
contentClassstring | string[]—Extra classes on the inner content wrapper.

Slots: #header, #body, #footer.

Built on the native Popover API and CSS anchor positioning — supported in current Chromium and Safari; check browser support for your audience.

CSS variables

Set these on :root, or on any wrapper to restyle only the popovers inside it. The sm and lg sizes keep their own width and height, and on small screens the panel fills the viewport minus --cffy-popover-spacing.

:root {
  --cffy-popover-radius: var(--cffy-radius-xl);
  --cffy-popover-offset: var(--cffy-space-16);
}
VariableDefaultControls
--cffy-popover-bg-color / --cffy-popover-color--cffy-surface-overlay / --cffy-on-backgroundPanel background and text
--cffy-popover-border-color--cffy-outline-surfacePanel border and the footer divider
--cffy-popover-radius--cffy-shape-container (12px)Panel corners
--cffy-popover-shadow--cffy-shadow-lgPanel shadow
--cffy-popover-max-width / --cffy-popover-max-height--cffy-container-xs (20rem) / 30remPanel size limits
--cffy-popover-spacing--cffy-space-16Space around the header and footer; the content padding is half of it
--cffy-popover-offset0.625remDistance from the trigger
--cffy-popover-title-font-size / --cffy-popover-title-font-weight--cffy-fs-xs / --cffy-fw-700Header title
--cffy-popover-subtitle-font-size / --cffy-popover-subtitle-color--cffy-fs-3xs / --cffy-muted-a10Header subtitle
--cffy-popover-easing / --cffy-popover-durationease-in-out / --cffy-duration-250Open and close animation
Copyright © 2026