Popover
A popover is a small panel that opens next to a button and can hold buttons, links, and fields. It doesn't block the page.
<tk-popover label="Filters"> <tk-button slot="trigger">Filters</tk-button> <tk-checkbox>Open</tk-checkbox> <tk-checkbox>Closed</tk-checkbox> <tk-button size="small" variant="primary">Apply</tk-button> </tk-popover>
Anatomy
| Part | What it is |
|---|---|
tk-popover |
the element; it opens and closes the panel and wires the ARIA |
trigger slot |
one button that opens it: a tk-button or tk-icon-button |
| default slot | the content, interactive or not |
surface part |
the panel |
There is no arrow, header, footer, or close button. Compose your own inside the content.
Trigger modes
Engineer in London. 168 followers.
<tk-popover trigger="hover" label="Ada Lovelace"> <tk-button slot="trigger" variant="ghost">Ada Lovelace</tk-button> <p>Engineer in London. 168 followers.</p> <tk-button size="small">Follow</tk-button> </tk-popover>
click(default): a click,Enter, orSpaceon the trigger opens and closes the panel. Use it for anything people open on purpose.hover: opens on pointer hover, on keyboard focus, and on a touch tap, so everyone can reach it. Use it for previews whose content is also available elsewhere.- Opening never moves focus into the panel. Keyboard users press
Tabto reach the content, which comes right after the trigger.
Opening and closing
- The panel closes on
Esc, on a press outside, when focus leaves it, and when the trigger scrolls out of view.Escreturns focus to the trigger. - In
hovermode, it opens after 400ms of hover and closes 300ms after the pointer leaves, so the pointer can move onto the panel. Focus and tap open it at once. - It never closes on a timer.
- It opens below the trigger and moves above when there's no room below. It shows instantly, with no animation.
show(),hide(), andtoggle()open and close it from code.
Contextual help
To explain a setting or field, put a short heading, a sentence or two, and at most one link behind an info button.
Billing cycles
Your cycle starts the day you subscribe and renews on the same date each month.
<tk-popover label="About billing cycles"> <tk-icon-button slot="trigger" label="About billing cycles"><tk-icon name="info"></tk-icon></tk-icon-button> <h4>Billing cycles</h4> <p>Your cycle starts the day you subscribe and renews on the same date each month.</p> <tk-link href="/billing">Read more about billing</tk-link> </tk-popover>
- Use
click, nothover: help is something people open on purpose. - Name the icon button with
label, and name the panel too. - Never put the only copy of essential information here. If people need it to succeed, put it on the page.
Sizing
- The panel fits its content up to 320px wide. Change that with
--tk-popover-max-width. - Set
--tk-popover-max-heightto cap the height; the content then scrolls vertically. - Set
--tk-popover-padding: 0to let an image reach the panel's edge.
When to use
- Use a popover for content people act on near its trigger: a filter panel, a profile card, a share panel, a short explanation of a setting.
- Use a
Tooltip for short text with nothing to click. - Use a
Menu for a list of commands. - Use a
Dialog when the task must block the page, or the content is too wide or too important for a small panel.
Content
- Keep it small: a heading, a few lines, a few controls.
- Name the panel after its trigger: a "Filters" button opens a panel named "Filters".
- Use sentence case.
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Put controls people act on in a popover | Put short text with nothing to click; use a tooltip |
| Use a menu for a list of commands | Put a command list in a popover |
Use hover for previews that are also elsewhere |
Hide the only copy of key information behind hover |
| Name an icon-only trigger | Leave the trigger or the panel unnamed |
| Use a dialog when the task must block the page | Nest a popover in a popover |
Related
Tooltip : short text, nothing to click.Menu : a list of commands.Dialog : a modal for a task that blocks the page.Sheet : a modal panel from an edge of the screen.
API
Attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
trigger |
click | hover |
click |
how it opens: click, or hover with focus and tap |
label |
string | the trigger's name | the panel's accessible name |
Slots
| Slot | Content |
|---|---|
trigger |
one tk-button or tk-icon-button, or one wrapped in a |
| default | the content, including interactive elements |
Methods and properties
| Name | What it does |
|---|---|
show() |
opens the panel |
hide() |
closes it |
toggle() |
opens or closes it |
open |
true while open; the open attribute mirrors it but doesn't open anything |
Events
No custom events.
CSS
::part(surface): the panel.--tk-popover-padding: the inner padding. Defaultspace-16.--tk-popover-max-width: the maximum width. Default320px.--tk-popover-max-height: the maximum height. Defaultnone.
Tokens
| Part | Tokens |
|---|---|
| panel | surface/raised, shadow-2, radius-16; in high contrast, a 1px border/default |
| text | text/default |
| padding | space-16 |
| gap to the trigger | space-4 |
Values per theme:
Accessibility
Built in:
- The trigger gets
aria-haspopup="dialog"andaria-expanded. - The panel is a non-modal
role="dialog", named bylabelor by the trigger's name. - Focus stays where it is on open;
Tabmoves into the content in page order, and leaving it closes the panel. Esccloses only the popover, not an overlay around it, and returns focus to the trigger.- In
hovermode, the panel can be dismissed withEsc, hovered without closing, and never times out.
Your part:
- Keep everything inside usable with the keyboard, with no focus traps.
- Name an icon-only trigger with
label. - Don't put a popover inside another popover.
| Key | Action |
|---|---|
Enter / Space |
on the trigger in click mode: opens or closes |
Tab |
moves from the trigger into the content; past the last item, leaves and closes |
Esc |
closes and returns focus to the trigger |