Tooltip
One line of text on hover or keyboard focus, from one attribute. No script needed.
A tooltip is one attribute and needs no script
data- shows its text above the element
on hover or keyboard focus. The text is plain text taken from the
attribute.
<button type="button" class="btn" data-tooltip="Add to collection">Hover</button>
data-side puts it above, below, left or right
<div class="stack" data-direction="row" data-gap="sm">
<button type="button" class="btn" data-tooltip="Above, the default" data-side="top">Top</button>
<button type="button" class="btn" data-tooltip="Below" data-side="bottom">Bottom</button>
<button type="button" class="btn" data-tooltip="Left" data-side="left">Left</button>
<button type="button" class="btn" data-tooltip="Right" data-side="right">Right</button>
</div>
data-align lines it up with the start, the centre or the end
On the left or right side, start is the top edge and end the bottom edge.
<div class="stack" data-direction="row" data-gap="sm">
<button type="button" class="btn" data-tooltip="Lined up with the start" data-align="start">Start</button>
<button type="button" class="btn" data-tooltip="Centred, the default" data-align="center">Center</button>
<button type="button" class="btn" data-tooltip="Lined up with the end" data-align="end">End</button>
</div>
An icon button keeps its aria-label: the tooltip is not its name
A screen reader does not read the tooltip, so the button is named
by aria-.
<div class="stack" data-direction="row" data-gap="sm">
<button type="button" class="btn" data-size="icon" aria-label="Copy" data-tooltip="Copy"><i class="icon icon-copy" aria-hidden="true"></i></button>
<button type="button" class="btn" data-size="icon" aria-label="Download" data-tooltip="Download"><i class="icon icon-download" aria-hidden="true"></i></button>
<button type="button" class="btn" data-size="icon" data-variant="danger" aria-label="Delete" data-tooltip="Delete"><i class="icon icon-trash-2" aria-hidden="true"></i></button>
</div>
It works on any element that can hold content: a badge, an icon, a word
An
abbr gets a dotted underline. Give an element that is
not focusable tabindex= when keyboard users
need the text too.
<div class="stack" data-direction="row">
<span class="badge" data-variant="ok" data-tooltip="Paid on Oct 3, 2026">Paid</span>
<span data-tooltip="Verified by 3D Secure"><i class="icon icon-shield-check" aria-hidden="true"></i></span>
<abbr data-tooltip="Monthly recurring revenue" tabindex="0">MRR</abbr>
</div>
A field cannot draw a tooltip itself, so the attribute goes on a wrapper
input, select, textarea and
img have no ::after. The wrapper shows
the tooltip on hover and while the field inside it has keyboard
focus.
<div class="field" data-tooltip="Letters and numbers only" data-align="start" style="max-width: 16rem">
<label for="tt-coupon">Coupon code</label>
<input id="tt-coupon" type="text" placeholder="SALE2026">
</div>
Long text stays on one line and is cut off at 320px
Text wider than 20rem (320px) ends in an ellipsis. Use a popover for anything longer.
<button type="button" class="btn" data-tooltip="This payment was captured on the first attempt and settled the next business day" data-align="start">Long text</button>
What a tooltip does not do
| Limit | What to do |
|---|---|
| It shows on hover and keyboard focus only; a touch screen has no hover. | Never put information only in a tooltip. |
| A screen reader does not read it. |
Name an icon button with aria-.
|
| One line of plain text, cut off at 320px; no links, buttons or formatting. | Use a popover. |
| These cannot draw one. | Put it on a wrapper. |
An element that already uses ::after cannot
have one.
|
Put it on a wrapper. |
| A scrolling area cuts it off at its edge. | Choose a side that points into the area. |
| Near the right edge it reaches past the window. |
Give that element
data-.
|
| It never flips to another side. | Choose them for where the element sits. |
Attributes
| Attribute / element | Values | Description |
|---|---|---|
data-
|
text | The text, plain, one line. On any element that can hold content. |
data-
|
none or top (default), bottom,
left, right
|
The side of the element the tooltip is on. |
data-
|
none or center (default), start,
end
|
Above or below: left edge, centre, right edge. Left or right: top edge, centre, bottom edge. |
aria-
|
text | Names an icon-only button; the tooltip does not. |
tabindex=
|
on a non-focusable element | Lets keyboard users focus it and see the tooltip. |
abbr[
|
A word or abbreviation with a dotted underline. |