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); } }}