Skip to main content

Theme config

Theme mode

Color palette

Grays

Border radii/radiuses/radiopedes/you know
Border radius
Field border radius
Button border radius
All
Components
Guides
API
Recent

Components

Tooltip

Built on top of Anchor.

Full support Supported since v144. Full support Supported since v149. Partial support Missing: popover-hint.

Add the .ui-tooltip class alongside .ui-anchor on the wrapper. Wire interestfor on the trigger to the .ui-anchor-floating[popover="hint"] element's ID.

Basics

Text only...

Set the tooltip text inside .ui-anchor-floating[popover="hint"].

Save your changes
<span class="ui-anchor ui-tooltip">
<button
class="ui-button"
interestfor="tooltip-basic"
commandfor="tooltip-basic"
command="toggle-popover"
>
Save
</button>
<span class="ui-anchor-floating" id="tooltip-basic" popover="hint"
>Save your changes</span
>
</span>

... or any markup you want

You can place any markup you want (famous last words) inside .ui-anchor-floating[popover="hint"], not only text.

Press + K to open the command palette.
<span class="ui-anchor ui-tooltip">
<button
class="ui-button"
interestfor="tooltip-rich"
commandfor="tooltip-rich"
command="toggle-popover"
>
Keyboard shortcuts
</button>
<span class="ui-anchor-floating" id="tooltip-rich" popover="hint">
Press <kbd></kbd> + <kbd>K</kbd> to open the command palette.
</span>
</span>

Alignment

Set --anchor-position-area on the parent with your preferred position-area value.

Above Before After Below
<div class="tooltip-alignment-grid">
<span
class="ui-anchor ui-tooltip"
style="--anchor-position-area: block-start"
>
<button
class="ui-button"
interestfor="tooltip-top"
commandfor="tooltip-top"
command="toggle-popover"
>
Top
</button>
<span class="ui-anchor-floating" id="tooltip-top" popover="hint"
>Above</span
>
</span>
<span
class="ui-anchor ui-tooltip"
style="--anchor-position-area: inline-start"
>
<button
class="ui-button"
interestfor="tooltip-start"
commandfor="tooltip-start"
command="toggle-popover"
>
Start
</button>
<span class="ui-anchor-floating" id="tooltip-start" popover="hint"
>Before</span
>
</span>
<span class="ui-anchor ui-tooltip" style="--anchor-position-area: inline-end">
<button
class="ui-button"
interestfor="tooltip-end"
commandfor="tooltip-end"
command="toggle-popover"
>
End
</button>
<span class="ui-anchor-floating" id="tooltip-end" popover="hint"
>After</span
>
</span>
<span class="ui-anchor ui-tooltip" style="--anchor-position-area: block-end">
<button
class="ui-button"
interestfor="tooltip-bottom"
commandfor="tooltip-bottom"
command="toggle-popover"
>
Bottom
</button>
<span class="ui-anchor-floating" id="tooltip-bottom" popover="hint"
>Below</span
>
</span>
</div>
<style>
.tooltip-alignment-grid {
display: grid;
gap: var(--size-3);
grid-template-areas:
". top . "
"start . end"
". bottom . ";
justify-items: center;
align-items: center;
}
.tooltip-alignment-grid > :nth-child(1) {
grid-area: top;
}
.tooltip-alignment-grid > :nth-child(2) {
grid-area: start;
}
.tooltip-alignment-grid > :nth-child(3) {
grid-area: end;
}
.tooltip-alignment-grid > :nth-child(4) {
grid-area: bottom;
}
</style>

Arrow

Add the .ui-with-arrow class on the .ui-tooltip. This would be cool to solve with corner-shape one day.

Save your changes
<span class="ui-anchor ui-tooltip ui-with-arrow">
<button
class="ui-button"
interestfor="tooltip-arrow"
commandfor="tooltip-arrow"
command="toggle-popover"
>
Save
</button>
<span class="ui-anchor-floating" id="tooltip-arrow" popover="hint"
>Save your changes</span
>
</span>

API

Type Modifiers Default Description
Container .ui-anchor.ui-tooltip - Wrapper element. Combines the anchor primitive with the tooltip styling.
Floating .ui-anchor-floating[popover="hint"] - Floating tooltip surface. Uses the hint popover so it auto-shows on interestfor hover/focus.
Trigger interestfor="id" - Add to the trigger element pointing to the floating element's ID. Pair with commandfor and command="toggle-popover" for touch support.
Arrow .ui-with-arrow - Add to the .ui-tooltip wrapper to render an arrow pointing from the tooltip toward the trigger.
Position --anchor-position-area block-start CSS custom property. Any valid position-area value.

Browser support

Full support Supported since v144. Full support Supported since v149. Partial support Missing: popover-hint.

See also the full browser support guide.

Installation

@layer components.extended {
:where(.ui-tooltip) {
--_tooltip-bg: light-dark(var(--gray-13), var(--gray-3));
--_tooltip-color: light-dark(var(--gray-1), var(--gray-15));
--_tooltip-offset: var(--size-2);
& > .ui-anchor-floating {
background-color: var(--_tooltip-bg);
border-radius: var(--radius-2);
color: var(--_tooltip-color);
font-size: var(--font-size-05);
line-height: 1.3;
margin: var(--_tooltip-offset);
max-inline-size: 240px;
/* UA sets overflow: auto on [popover], which clips the arrow. */
overflow: visible;
padding-block: var(--size-1);
padding-inline: var(--size-2);
position-area: var(--anchor-position-area, block-start);
position-try-fallbacks:
flip-block,
flip-inline,
flip-block flip-inline;
position-visibility: anchors-visible;
text-align: center;
text-wrap: pretty;
}
/* Optional arrow pointing from the tooltip toward the trigger.
Anchored to the same --anchor so it flips together with the
tooltip when position-try-fallbacks kicks in. */
&.ui-with-arrow {
--_arrow-size: var(--size-2);
& > .ui-anchor-floating {
/* Reserve space so the arrow doesn't overlap the trigger. */
--_tooltip-offset: calc(var(--size-2) + var(--_arrow-size) / 2);
}
& > .ui-anchor-floating::before {
background-color: var(--_tooltip-bg);
block-size: var(--_arrow-size);
content: "";
inline-size: var(--_arrow-size);
inset-block-end: calc(var(--_arrow-size) / -2);
inset-inline-start: 50%;
position: absolute;
rotate: 45deg;
translate: -50% 0;
}
}
/* Fade */
& > .ui-anchor-floating[popover] {
opacity: 0;
transition:
display 0.15s allow-discrete,
opacity 0.15s var(--ease-out-1),
overlay 0.15s allow-discrete;
&:popover-open {
opacity: 1;
@starting-style {
opacity: 0;
}
}
}
}
}
@layer components.root {
:where(.ui-anchor) {
anchor-name: --anchor;
anchor-scope: --anchor;
display: inline-block;
inline-size: fit-content;
/* Always-visible */
& > .ui-anchor-floating:not([popover]) {
block-size: max-content;
inline-size: max-content;
position: absolute;
position-anchor: --anchor;
position-area: var(--anchor-position-area, start end);
translate: var(--_anchor-tx, 0) var(--_anchor-ty, 0);
}
/* Hover-triggered */
& > .ui-anchor-floating[popover] {
inset: unset;
margin: 0;
position: absolute;
position-area: var(--anchor-position-area, start end);
translate: var(--_anchor-tx, 0) var(--_anchor-ty, 0);
}
}
}

See also