Overlay Components
[06] Overlay Components
Tooltip
A short ink label that describes its trigger on hover and keyboard focus. Comes in sizes xs to xl and takes Popup props directly.
Basic usage
Tooltip describes its trigger with a short hint on hover and on keyboard focus. Pass the trigger as the child and the hint as content. The hint renders as an ink label: near-black in light mode, near-white in dark mode.
<Tooltip content="Saves without leaving the page"> <Button>Save</Button></Tooltip>The trigger must accept a ref. Button, IconButton, Badge, Link and the other element components do.
Tooltip takes Popup props directly (size, appearance, variant, shape, placement, arrow, offset, className and the rest), and they style the label. Its own props are content, open, defaultOpen, onOpenChange, openDelay (default 300), closeDelay (default 100), popupProps, popupId and disabled.
Keyboard and pointer
A tooltip that only opens on hover is invisible to keyboard users, so Tooltip opens on focus too. Tab to the second button to see it.
<Row flexWrap> <Tooltip content="Opens on hover"> <Button secondary>Hover me</Button> </Tooltip> <Tooltip content="Opens on focus as well"> <Button secondary>Tab to me</Button> </Tooltip></Row>Sizes
Tooltip defaults to sm. Its text, padding and corner radius follow its own size, xs to xl, and the text sits one font step under a Button of the same size. The tooltip does not shrink on phones.
<Row flexWrap> <Tooltip xs content="An xs tooltip"> <Button xs>xs</Button> </Tooltip> <Tooltip content="An sm tooltip, the default"> <Button>sm</Button> </Tooltip> <Tooltip md content="An md tooltip"> <Button md>md</Button> </Tooltip> <Tooltip lg content="An lg tooltip"> <Button lg>lg</Button> </Tooltip> <Tooltip xl content="An xl tooltip"> <Button xl>xl</Button> </Tooltip></Row>Placement
Tooltip opens above its trigger and flips to the other side when there is no room. All twelve place* props from Popup work on Tooltip directly, and arrow adds a pointer. Top and bottom tooltips stay on screen when the trigger sits at the edge of the viewport.
<Row flexWrap> <Tooltip content="Above"> <Button>Top</Button> </Tooltip> <Tooltip placeBottom content="Below"> <Button>Bottom</Button> </Tooltip> <Tooltip placeRight content="To the right"> <Button>Right</Button> </Tooltip> <Tooltip placeRight arrow content="Points at its trigger"> <Button>Arrow</Button> </Tooltip></Row>Long hints
A long hint wraps inside a width cap that grows with size, from 16 to 32rem across xs to xl and 20rem at the default sm, instead of running across the page.
<Tooltip content="Archiving moves the conversation out of your inbox. Replies bring it back, and nothing is deleted."> <Button secondary>Archive</Button></Tooltip>Color and shape
Appearance, variant and shape props restyle the label. secondary restores the gray look of earlier versions.
<Row flexWrap> <Tooltip content="Ink, the default"> <Button>default</Button> </Tooltip> <Tooltip secondary content="Gray"> <Button>secondary</Button> </Tooltip> <Tooltip danger content="Deletes the project for everyone"> <Button danger>danger</Button> </Tooltip> <Tooltip sharp content="Sharp corners"> <Button>sharp</Button> </Tooltip> <Tooltip outline danger border content="Outline danger"> <Button>outline danger</Button> </Tooltip></Row>To change every tooltip in an app, set the default once on ThemeProvider:
<ThemeProvider themeDefaults={{ tooltip: { secondary: true } }}> <App /></ThemeProvider>popupProps is still supported and is combined with the direct props, which helps when several tooltips share one props object. Pass one value per category (one size, one appearance, and so on) across the two.
Delays
openDelay keeps tooltips from flashing as the pointer crosses the screen. closeDelay gives the pointer time to move onto the tooltip itself.
<Row flexWrap> <Tooltip content="Appears at once" openDelay={0}> <Button>No delay</Button> </Tooltip> <Tooltip content="Waits half a second" openDelay={500}> <Button>Slow</Button> </Tooltip></Row>Accessibility
A tooltip describes its trigger, so while it is open the trigger carries aria-describedby pointing at it. It never gets aria-haspopup or aria-expanded, because those describe a disclosure, not a description, and there is no aria-haspopup value for tooltips.
Keep the content short and non-essential. Anything the user must read to complete a task belongs in the page, not behind a hover.
Icon-only triggers
A common use is explaining a control that has no visible label.
API key
<Row> <Text sm>API key</Text> <Tooltip content="Rotating the key invalidates the old one immediately"> <IconButton secondary aria-label="About API keys">?</IconButton> </Tooltip></Row>Tooltip Props
| Prop | Category | Default | Description |
|---|---|---|---|
accent | Appearance | Accent color appearance (rose) | |
danger | Appearance | Danger color appearance (red) | |
info | Appearance | Info color appearance (cyan) | |
inheritAppearance | Appearance | Inherit appearance from parent — suppresses own data-appearance/data-variant, uses parent's CSS variables | |
primary | Appearance | ✓ | Primary color appearance (gray) |
secondary | Appearance | Secondary color appearance (gray) | |
success | Appearance | Success color appearance (green) | |
tertiary | Appearance | Tertiary color appearance | |
warning | Appearance | Warning color appearance (amber) | |
flex1 | Flex | Take up remaining space (= | |
flexAuto | Flex | Grow but respect intrinsic size (= | |
flexNone | Flex | Don't grow and don't shrink (= | |
fontHeading | Font Family | Heading font family (defaults to sans, customizable via --font-heading) — emits font-heading | |
fontMono | Font Family | Monospace font family — emits font-mono | |
fontSans | Font Family | ✓ | Sans-serif font family (default) — emits font-sans |
fontSerif | Font Family | Serif font family — emits font-serif | |
italic | Font Style | Italic font style | |
notItalic | Font Style | Not italic (normal) font style | |
fontBlack | Font Weight | Black font weight (900) — emits font-black | |
fontBold | Font Weight | Bold font weight (700) — emits font-bold | |
fontExtrabold | Font Weight | Extra bold font weight (800) — emits font-extrabold | |
fontExtralight | Font Weight | Extra light font weight (200) — emits font-extralight | |
fontLight | Font Weight | Light font weight (300) — emits font-light | |
fontMedium | Font Weight | Medium font weight (500) — emits font-medium | |
fontNormal | Font Weight | Normal font weight (400) — emits font-normal | |
fontSemibold | Font Weight | Semibold font weight (600) — emits font-semibold | |
fontThin | Font Weight | Thin font weight (100) — emits font-thin | |
noPadding | Padding | Disable internal padding | |
padding | Padding | Enable internal padding | |
paddingX | Padding | Enable only horizontal padding | |
paddingY | Padding | Enable only vertical padding | |
placeBottom | Placement | Position below anchor, centered horizontally | |
placeBottomEnd | Placement | Position below anchor, aligned to end (right) | |
placeBottomStart | Placement | Position below anchor, aligned to start (left) | |
placeLeft | Placement | Position to the left of anchor, centered vertically | |
placeLeftEnd | Placement | Position to the left of anchor, aligned to bottom | |
placeLeftStart | Placement | Position to the left of anchor, aligned to top | |
placeRight | Placement | Position to the right of anchor, centered vertically | |
placeRightEnd | Placement | Position to the right of anchor, aligned to bottom | |
placeRightStart | Placement | Position to the right of anchor, aligned to top | |
placeTop | Placement | ✓ | Position above anchor, centered horizontally (default) |
placeTopEnd | Placement | Position above anchor, aligned to end (right) | |
placeTopStart | Placement | Position above anchor, aligned to start (left) | |
pill | Shape | Fully rounded corners (circular) | |
rounded | Shape | ✓ | Medium rounded corners (default) |
sharp | Shape | No rounded corners (square) | |
noShrink | Shrink | Prevent the flex item from shrinking below its content size (= | |
lg | Size | Large size | |
md | Size | Medium size (default) | |
sm | Size | ✓ | Small size |
xl | Size | Extra large size | |
xs | Size | Extra small size | |
textCenter | Text Align | Align text to center | |
textEnd | Text Align | Align text to the reading-direction end (right in LTR, left in RTL) | |
textJustify | Text Align | Justify text | |
textLeft | Text Align | Align text to left (physical side, does not flip under RTL) | |
textRight | Text Align | Align text to right (physical side, does not flip under RTL) | |
textStart | Text Align | Align text to the reading-direction start (left in LTR, right in RTL) | |
lineThrough | Text Decoration | Add strikethrough/line-through decoration across text | |
noUnderline | Text Decoration | Remove ALL text-decoration — underline, line-through, and overline (text-decoration: none) | |
overline | Text Decoration | Add overline decoration above text | |
underline | Text Decoration | Add underline decoration below text | |
capitalize | Text Transform | Capitalize first letter of each word | |
lowercase | Text Transform | Transform text to lowercase | |
normalCase | Text Transform | Normal text case (no transformation) | |
uppercase | Text Transform | Transform text to uppercase | |
lineClamp2 | Truncate | Truncate at 2 lines with ellipsis | |
lineClamp3 | Truncate | Truncate at 3 lines with ellipsis | |
lineClamp4 | Truncate | Truncate at 4 lines with ellipsis | |
lineClamp5 | Truncate | Truncate at 5 lines with ellipsis | |
noTruncate | Truncate | Remove truncation | |
truncate | Truncate | Single line truncation with ellipsis | |
filled | Variant | ✓ | Filled variant - solid background with contrasting text color |
ghost | Variant | Ghost variant - transparent background, no border, appearance-colored text, tinted hover background | |
outline | Variant | Outline variant - transparent background with border and colored text (default) |
Layout & utility props (gap, padding, hide, items, justify, ...) — documented on Common Props
| Prop | Category | Default | Description |
|---|---|---|---|
alignSelfAuto | Align Self | Use the parent's align-items value (align-self: auto) | |
alignSelfBaseline | Align Self | Align this item to its baseline (align-self: baseline) | |
alignSelfCenter | Align Self | Center this item on the cross axis (align-self: center) | |
alignSelfEnd | Align Self | Align this item to the end of the cross axis (align-self: flex-end) | |
alignSelfStart | Align Self | Align this item to the start of the cross axis (align-self: flex-start) | |
alignSelfStretch | Align Self | Stretch this item to fill the cross axis (align-self: stretch) | |
border | Border | Enable border on all sides | |
borderB | Border | Enable border on bottom | |
borderEnd | Border | Enable border on the inline-end side (right in LTR, left in RTL) | |
borderL | Border | Enable border on left | |
borderR | Border | Enable border on right | |
borderStart | Border | Enable border on the inline-start side (left in LTR, right in RTL) | |
borderT | Border | Enable border on top | |
borderX | Border | Enable border on left and right | |
borderY | Border | Enable border on top and bottom | |
noBorder | Border | ✓ | Disable all borders |
clampHeight | Clamp Height | Clamp to a size-dependent maximum height (uses --max-height CSS variable) | |
constrainWidth | Constrain Width | Constrain to a size-dependent minimum width (uses --popup-min-w CSS variable) | |
block | Display | Block display - takes full width, new line | |
contents | Display | Contents display - element's box is removed, children display as if parent didn't exist | |
flex | Display | ✓ | Flex display - flexbox container |
grid | Display | Grid display - CSS grid container | |
hidden | Display | Hidden display - element is not visible | |
inline | Display | Inline display - flows with text | |
inlineBlock | Display | Inline-block display - inline but with block properties | |
inlineFlex | Display | Inline-flex display - inline flexbox container | |
inlineGrid | Display | Inline-grid display - inline grid container | |
table | Display | Table display - behaves like table element | |
tableCell | Display | Table-cell display - behaves like td element | |
column | Flex Direction | ✓ | Flex direction column (vertical) |
columnReverse | Flex Direction | Flex direction column-reverse | |
row | Flex Direction | Flex direction row (horizontal) | |
rowReverse | Flex Direction | Flex direction row-reverse | |
gap | Gap | Enable gap spacing between children | |
noGap | Gap | ✓ | Disable gap spacing |
hAuto | Height | Set height to auto | |
hFit | Height | Set height to fit-content | |
hFull | Height | Set height to 100% | |
hScreen | Height | Set height to 100vh (viewport height), removes max-height constraint | |
desktopHide | Hide | Hide element on desktop devices and below (max-desktop: 80rem) | |
mobileHide | Hide | Hide element on mobile devices and below (max-mobile: 48rem) | |
tabletHide | Hide | Hide element on tablet devices and below (max-tablet: 64rem) | |
itemsBaseline | Items | Align items to baseline | |
itemsCenter | Items | Align items to center | |
itemsEnd | Items | Align items to end (bottom/right) | |
itemsStart | Items | Align items to start (top/left) | |
itemsStretch | Items | Stretch items to fill container | |
justifyAround | Justify | Distribute items with space around them | |
justifyBaseline | Justify | Align items along their baseline on main axis | |
justifyBetween | Justify | Distribute items with space between them | |
justifyCenter | Justify | Center items along the main axis | |
justifyEnd | Justify | Pack items toward the end of the main axis | |
justifyEvenly | Justify | Distribute items with equal space around them | |
justifyStart | Justify | Pack items toward the start of the main axis | |
justifyStretch | Justify | Stretch items to fill the main axis | |
justifySelfAuto | Justify Self | Use the parent's justify-items value (justify-self: auto) | |
justifySelfCenter | Justify Self | Center this item on the inline axis (justify-self: center) | |
justifySelfEnd | Justify Self | Align this item to the end of the inline axis (justify-self: end) | |
justifySelfStart | Justify Self | Align this item to the start of the inline axis (justify-self: start) | |
justifySelfStretch | Justify Self | Stretch this item to fill the inline axis (justify-self: stretch) | |
overflowAuto | Overflow | Auto overflow - show scrollbars if needed | |
overflowClip | Overflow | Clip overflow - hard clip without scrollbars | |
overflowHidden | Overflow | Hidden overflow - clip content without scrollbars | |
overflowScroll | Overflow | Scroll overflow - always show scrollbars | |
overflowVisible | Overflow | Visible overflow - content extends beyond bounds | |
overflowXAuto | Overflow | Auto overflow on X-axis only | |
overflowXClip | Overflow | Clip overflow on X-axis only | |
overflowXHidden | Overflow | Hidden overflow on X-axis only | |
overflowXScroll | Overflow | Scroll overflow on X-axis only | |
overflowXVisible | Overflow | Visible overflow on X-axis only | |
overflowYAuto | Overflow | Auto overflow on Y-axis only | |
overflowYClip | Overflow | Clip overflow on Y-axis only | |
overflowYHidden | Overflow | Hidden overflow on Y-axis only | |
overflowYScroll | Overflow | Scroll overflow on Y-axis only | |
overflowYVisible | Overflow | Visible overflow on Y-axis only | |
pointerEventsAuto | Pointer Events | Enable pointer events (default browser behavior) | |
pointerEventsNone | Pointer Events | Disable pointer events - clicks pass through the element | |
absolute | Position | Absolute positioning | |
fixed | Position | ✓ | Fixed positioning |
relative | Position | Relative positioning | |
static | Position | Static positioning | |
sticky | Position | Sticky positioning | |
responsiveSizing | Responsive Sizing | Enable responsive sizing - uses breakpoint-specific classes for font size, padding, and gap | |
insetRing | Ring | Enable the inset ring — emits ring-inset | |
noInsetRing | Ring | ✓ | Disable the inset ring |
noShadow | Shadow | Disable drop shadow | |
shadow | Shadow | ✓ | Enable drop shadow |
noTransition | Transition | Disable transitions for instant state changes | |
transition | Transition | Enable smooth transitions between states | |
transparent | Transparent | Disable background color - makes component background transparent | |
wAuto | Width | Set width to auto | |
wFit | Width | ✓ | Set width to fit-content |
wFull | Width | Set width to 100% | |
wScreen | Width | Set width to 100vw (viewport width), removes max-width constraint | |
flexNoWrap | Wrap | Force flex items to stay on single line (may overflow) | |
flexWrap | Wrap | Allow flex items to wrap to new lines when container is too narrow | |
flexWrapReverse | Wrap | Wrap flex items in reverse order (last items wrap first) |