Popover
NewA floating content panel anchored near a trigger element, built on the native HTML Popover API. No JavaScript or third-party library required.
API Reference
Supported in all modern browsers (Chrome 114+, Firefox 125+, Safari 17+). No polyfill needed.
c-popover
| Attribute | Description | Type | Default |
|---|---|---|---|
id
|
Connects the popover panel to its trigger via popovertarget. Auto-generated when omitted.
|
string |
auto
|
manual
|
Sets popover="manual" — light-dismiss (click outside) is disabled; must close explicitly.
|
boolean |
False
|
c-popover.trigger
A <button popovertarget="..."> styled as a button. Accepts the same
color, variant, and size
props as c-button.
| Attribute | Description | Type | Default |
|---|---|---|---|
for
|
The id of the target c-popover panel
|
string |
""
|
color
|
Button color theme | string |
""
|
variant
|
Button style variant | string |
""
|
size
|
Button size | string |
"md"
|
getBoundingClientRect.
In your own app, drop in the same script or swap it for
Floating UI
for more placement options (right, left, smart flip).
Accessibility
Top layer: the Popover API promotes the panel to the browser's top layer, so it always
renders above other content — no z-index juggling needed.
Focus management: the browser automatically moves focus into the popover when it opens. Ensure the first focusable element inside the panel is meaningful (e.g. a close button or primary action).
Light dismiss: default (auto) popovers close on click-outside and
Escape, which matches user expectations. Only use
manual when an explicit dismiss action is required.
Trigger labels: icon-only triggers must have an
aria-label so screen reader users understand the button's purpose.
Examples
Usage
<c-popover.trigger for="my-pop" color="primary">Open</c-popover.trigger>
<c-popover id="my-pop">Panel content</c-popover>
Basic Popover
About this feature
This popover is rendered in the browser's top layer and dismisses automatically on click-outside.
A simple text popover with no extra markup.
<c-popover.trigger for="info-pop" color="primary">Show Info</c-popover.trigger>
<c-popover id="info-pop">
<p class="text-sm font-medium mb-1">About this feature</p>
<p class="text-sm text-base-content/70">
This popover dismisses automatically on click-outside.
</p>
</c-popover>
Rich Content Popover
All systems operational
<c-popover.trigger for="user-pop" color="secondary">User Profile</c-popover.trigger>
<c-popover id="user-pop" class="min-w-[16rem]">
<div class="flex items-center gap-3 mb-3">
<!-- avatar + name -->
</div>
<div class="divider my-2"></div>
<a href="#" class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-base-200 text-sm">
View Profile
</a>
</c-popover>
Manual Popover (No Light-Dismiss)
Action required
Your trial expires in 3 days. Upgrade your plan to avoid service interruption.
<c-popover.trigger for="notice-pop" color="warning">Important Notice</c-popover.trigger>
<!-- manual: light-dismiss is disabled; must close explicitly -->
<c-popover id="notice-pop" manual class="max-w-xs">
<p class="text-sm font-semibold mb-1">Action required</p>
<p class="text-sm text-base-content/70">Your trial expires in 3 days.</p>
<div class="flex gap-2 justify-end mt-3">
<button
type="button"
popovertarget="notice-pop"
popovertargetaction="hide"
class="btn btn-xs btn-ghost"
>
Dismiss
</button>
<c-button color="warning" size="xs">Upgrade Now</c-button>
</div>
</c-popover>
Custom Trigger
<!-- Any button with popovertarget works as a trigger -->
<button type="button" popovertarget="help-pop"
class="btn btn-circle btn-ghost btn-sm"
aria-label="Help">
<c-icon name="help-circle" size="18" />
</button>
<c-popover id="help-pop">
<p class="text-sm font-medium mb-1">Need help?</p>
<a href="#" class="link link-primary text-sm">View docs</a>
</c-popover>