Tooltip
Tooltips display informative text when users hover, focus, or tap an interactive element.
Make sure to read the Accessibility section for best practices before using tooltips.
Usage
Wrap Tooltip
around the element you want to use as the “trigger”, and pass the tooltip text into the content
prop.
import * as React from 'react';
import { Tooltip, Button } from '@itwin/itwinui-react';
export default () => {
return (
<Tooltip content='I am a tooltip'>
<Button>Please, hover me!</Button>
</Tooltip>
);
};
For everything to work correctly, the trigger element must:
- be an interactive element, for example, a
<button>
- forward its ref
- delegate (spread) any arbitrary props to the underlying DOM node
Positioning
Tooltip
handles positioning using an external library called Floating UI. To control which side the tooltip should be placed relative to its trigger, use the placement
prop (which defaults to "top"
). If enough space is not available, then it will automatically flip to the opposite side.
import * as React from 'react';
import { Tooltip, Button } from '@itwin/itwinui-react';
export default () => {
return (
<div className='demo-container'>
<Tooltip placement='left' content='left tooltip'>
<Button>Left</Button>
</Tooltip>
<Tooltip placement='top' content='top tooltip'>
<Button>Top</Button>
</Tooltip>
<Tooltip placement='bottom' content='bottom tooltip'>
<Button>Bottom</Button>
</Tooltip>
<Tooltip placement='right' content='right tooltip'>
<Button>Right</Button>
</Tooltip>
</div>
);
};
There are some advanced props available for more granular control over positioning, such as autoUpdateOptions
and middleware
. These are rarely needed in practice.
Portals
It is important to know that before calculating the position, the tooltip gets portaled to the end of <body>
. This is done to avoid stacking context issues in browsers where the popover
API is not supported. This portaling behavior can be controlled using the Tooltip’s portal
prop or the ThemeProvider’s portalContainer
prop.
Accessibility
Tooltip
has a few built-in accessibility features to help satisfy WCAG Success Criterion 1.4.13.
- The tooltip will be shown when the trigger element is focused (e.g. using the Tab key).
- The tooltip can be dismissed using the Escape key.
- The content can be hovered over using a mouse pointer, instead of always disappearing when the pointer leaves the trigger element.
- For screen-reader support, the tooltip will be associated with the trigger element using
aria-describedby
by default. This behavior is controllable using theariaStrategy
prop.
Best practices
-
Tooltips should only be used to display supplemental information. Do not use tooltips to display critical information, or as a means to navigate an interface. Functionality of the product should not be dependent on the user reading tooltips.
-
Tooltip content should consist of short plain text, up to 256 characters. Do not use content other than text, such as links, pictures, tables, etc. If you need to display more interactive content, consider using a Popover instead.
-
Tooltips should only be triggered by interactive elements, such as buttons, which can be focused using keyboard. Do not use tooltips for revealing truncated text and do not use plain icons as the trigger, as this pattern will not be accessible to keyboard users or screen-reader users.
-
Touchscreen devices do not have a hover state. Be cautious when using tooltips, since there is no determined way of replacing tooltips on mobile devices or tablets.
IconButtons
If you are using an IconButton
as the trigger, you can pass the label
prop to it, instead of wrapping it in a Tooltip
component. This will automatically add the tooltip functionality to the button and handle some other accessibility considerations as well.
Props
Prop | Description | Default |
---|---|---|
content | Content of the tooltip. ReactNode | |
children | Element to have tooltip on. Has to be a valid JSX element and needs to forward its ref.
If not specified, the reference prop should be used instead.ReactNode | |
portal | Where should the element be portaled to? If true, it will portal into nearest ThemeProvider's portalContainer. If false, it will not be portaled. Otherwise, it will portal to the element passed to to .If to /to() === null /undefined , the default behavior will be used (i.e. as if portal is not passed).boolean | { to: HTMLElement | (() => HTMLElement); } | true |
placement | Placement of the Tooltip Placement | 'top' |
visible | Property for manual visibility control boolean | |
onVisibleChange | Callback invoked every time the tooltip visibility changes as a result
of internal logic. Should be used alongside visible prop.(visible: boolean) => void | |
autoUpdateOptions | autoUpdate options that recalculates position
to ensure the floating element remains anchored
to its reference element, such as when scrolling
and resizing the screen.
@see floating-ui docs { ancestorScroll?: boolean; ancestorResize?: boolean; elementResize?: boolean; animationFrame?: boolean; layoutShift?: boolean; } | |
middleware | Tooltip middleware options.
@see floating-ui docs { offset?: number; flip?: boolean; shift?: boolean; size?: boolean; autoPlacement?: boolean; hide?: boolean; inline?: boolean; } | |
reference | Sets reference point to user provided element. HTMLElement | |
ariaStrategy | By default, the tooltip will be associated with the reference element
using aria-describedby .Pass "label" if you want to use aria-labelledby instead, or pass "none"
if you don't want any association."label" | "none" | "description" | 'description' |
id | string | |
as | "symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...> |