Tooltip
Provide a floating label or hint that appears on hover/focus.
Basic example
Wrap an element in a tooltip. Hovering or focusing the element will reveal the tooltip. Use Tooltips to indicate what action clicking an element will perform, or to show additional information about something.
Editable example<Tooltip content="Tooltip content">
<Button type="secondary">Hover/focus</Button>
</Tooltip>
Best practices
- Avoid rendering any interactive elements within a Tooltip. Tooltips are primarily for text/images and are finnicky to interact with if they contain buttons, links, or controls. Consider using a if you need to contextually disclose interactive controls.
- Be clear and descriptive, but to the point. Avoid unnecessary words and try to stick to 1—3 for small Tooltips.
- If an action is clear enough, a Tooltip isn't really necessary. For example, an
xicon in a modal dialog is ubiquitously understood to mean close, so doesn't require a Tooltip.
Position
Set a preferred position for the Tooltip. If there's not enough space in the viewport it'll automatically flip to the opposite side. The default position is TooltipPosition.Top.
Editable example<Tooltip position={TooltipPosition.Top} content="Tooltip content">
<Button type="secondary">Top</Button>
</Tooltip>
<Tooltip position={TooltipPosition.Bottom} content="Tooltip content">
<Button type="secondary">Bottom</Button>
</Tooltip>
<Tooltip position={TooltipPosition.Left} content="Tooltip content">
<Button type="secondary">Left</Button>
</Tooltip>
<Tooltip position={TooltipPosition.Right} content="Tooltip content">
<Button type="secondary">Right</Button>
</Tooltip>
Size
For basic 1—3 word hints, use the default size. For tooltips containing a sentence or paragraph, use TooltipSize.Large.
Editable example<Tooltip size={TooltipSize.Small} content="Small tooltip">
<Button type="secondary">Small</Button>
</Tooltip>
<Tooltip size={TooltipSize.Large} content="Large tooltip works better for longer lines of text">
<Button type="secondary">Large</Button>
</Tooltip>
Content
For simple use cases string content will do it, but sometimes Tooltips need to render different styled text or images. Just pass in any React nodes into the content prop and it'll render it. Just be careful not to render any interactive elements — Tooltips aren't designed to contain them.
Editable example<Tooltip
size={TooltipSize.Large}
content={
<>
<span className="text-small-label">Custom content</span>
<p>You can render any React components in here</p>
</>
}
>
<Button type="secondary">Hover/Focus</Button>
</Tooltip>
Wrap target
Sometimes the component wrapped by the Tooltip doesn't accept all of the props Tooltip needs to pass to its children. Use the wrapTarget prop to move all of the tooltip events and attributes from the target to the Tooltip's wrapping div.
Editable example<Tooltip
wrapTarget
content="Tooltip content"
>
<Card>
<div className="space-inset-s">Wrapped target</div>
</Card>
</Tooltip>
Controlled
Tooltips can be manually shown/hidden using the show prop.
Editable example() => {
const [showTooltip, setShowTooltip] = React.useState(false);
return (
<>
<Button
type="secondary"
decorator={ButtonDecorator.Arrow}
onClick={() => setShowTooltip(!showTooltip)}
>
Toggle tooltip
</Button>
<Tooltip
show={showTooltip}
content="Tooltip content"
>
<Button type="secondary">Target</Button>
</Tooltip>
</>
);
}
Conditionally Controlled Tooltips
For advanced use cases where we sometimes want to use a controlled Tooltip, we can pass a condition to the show prop like so:
show={isFoo ? undefined : false}
For example, a scenario where we want to use the built in hover behaviours to show/hide a Tooltip when the Tooltip has content, while hiding the Tooltip when there is no content. In this case, we can use both the content prop and the show prop together. This will use the default hover behaviour if there is content, and won't show the tooltip at all if there is no content.
Editable example() => {
const tooltipContent = undefined;
return (
<>
<Tooltip
size={TooltipSize.Large}
content={tooltipContent}
// Use the default hover behaviour if there is content, and don't show it at all if there is no content
show={tooltipContent ? undefined : false}
>
<Button type="secondary">Button</Button>
</Tooltip>
</>
);
}
We could also use this pattern for combining a Tooltip with components that don't have their own disabled state:
Editable example() => {
const isDisabled = true;
return (
<Tooltip
content="Explainer for why this is disabled"
// This tooltip will only show on hover if the Checkbox is disabled
show={isDisabled ? undefined : false}
wrapTarget
>
<Checkbox isDisabled={isDisabled} item={{ id: "1", value: "1", label: "Click me!" }} />
</Tooltip>
);
}
Accessibility
- Only use
wrapTargetif the target element is not interactive. Using this prop with an interactive target will cause the wrapper to take focus first, announcing the tooltip, then require a second tab to reach the interactive element within, which is a clunky user experience. It's better to update your interactive component to accept all of the propsTooltippasses to it. - Tooltips announce their content when the target is focused using a screen reader. If your tooltip only provides supplementary text and does not directly describe the target, make sure the target contains text or an
aria-labeldirectly describing itself.