Tucano v0.37.2

Tooltip

Short hint anchored to an element. It shows on pointer, keyboard focus and touch: a hint that only responds to the mouse doesn't exist for keyboard users, and never shows on a phone, where there's no hover.

Late fees and interest

Examples

Side and alignment are the same as shadcn's, and so is the default: top-center.

Sides

top, right, bottom and left. If it doesn't fit, it flips to the opposite side and the arrow follows.

Alignment

start, center and end along the side's axis. The arrow always points to the center of the trigger.

Long text

Wraps at 16rem wide; maxWidth changes it in JS.

Delay

data-delay="900" waits longer before showing on pointer. On focus, it shows right away.

How to use

The text goes in the attribute itself, and it initializes on its own, including whatever arrives later through HTMX.

<button data-tuc-tip="Generates the PDF with the current layout">Export</button>
<button data-tuc-tip="..." data-placement="right-center" data-delay="600">More</button>
<button data-tuc-tip title="Comes from the title">From title</button>
AttributeDefaultWhat it's for
data-tuc-tip—The hint text. When empty, uses the title
data-placementtop-centerSide and alignment
data-delay350Wait, in ms, before showing on pointer
data-tip-class—Extra class on the bubble, to change the color in a single case

With an empty data-tuc-tip, the text comes from the title, which is removed: otherwise the browser's native tooltip would show on top of ours. Without the attribute, no title is touched — hijacking every title on the page would be far too intrusive for a library. With neither text nor title, there's nothing to show, and the component logs an error to the console.

In a Django template

<span class="tuc-badge is-warning" data-tuc-tip="Due on {{ contract.due_date|date:'d/m/Y' }}">
  {{ contract.get_status_display }}
</span>

On an element that doesn't receive focus, like that <span>, the component adds tabindex="0": without it the hint wouldn't exist for keyboard users. Buttons, links and fields are already focusable and are left as they are.

In JavaScript

new Tucano.Tooltip('#export', {
  text: 'Generates the PDF',
  placement: 'right-center',
  delay: 350,         // on hover: avoids flicker when the mouse just brushes past
  delayOut: 120,      // on leave
  maxWidth: '20rem',
  className: 'tip-accent',
});

Color

Two variables, and the arrow reads the same ones: changing the bubble's color doesn't detach the tip. Set them for all tooltips, on .tuc-tip, or for a single case, with data-tip-class.

.tip-accent { --tuc-tip-bg: var(--tuc-accent); --tuc-tip-fg: var(--tuc-accent-fg); }
.tip-danger { --tuc-tip-bg: var(--tuc-danger-fill); --tuc-tip-fg: #fff; }
.tip-light  { --tuc-tip-bg: var(--tuc-bg); --tuc-tip-fg: var(--tuc-fg); box-shadow: var(--tuc-shadow); }
<button data-tuc-tip="Only administrators can delete" data-tip-class="tip-danger">Delete</button>

When it shows and when it hides

Only one hint stays open at a time: opening another closes the previous one.

What happensThe hint
The pointer entersShows after delay, 350 ms
The pointer leavesHides after delayOut, 120 ms
The element receives keyboard focusShows right away
Focus comes back after a click, as when a modal closesDoes not show
Focus leavesHides
Tap, on a touch screenTapping opens and closes it; tapping outside closes it
EscHides, even with the pointer resting on top
The trigger scrolls off screenHides, instead of getting stuck at the edge

Accessibility

The bubble is a role="tooltip", and the element points to it with aria-describedby: the screen reader reads the hint along with the button, as its description, and not as a stray element on the page.

Esc closes it with the pointer on top

It's not a detail: it's what WCAG 1.4.13 requires, for people using screen magnification who need to dismiss a hint covering the content without moving the mouse.

The hint is text only and doesn't receive the pointer. A link, a button or information the person needs to finish the task doesn't belong in it: anyone who doesn't point at or focus that element will never see it. The arrow is decoration and gets aria-hidden. With prefers-reduced-motion the hint shows and hides without animation.

API

Generated from the code on every build — if something is not here, it does not exist.

Markup
[data-tuc-tip]
In JS
new Tucano.Tooltip(alvo, opcoes)
Attributes
data-delay data-placement data-tip-class data-tuc-tip
Methods
setText destroy

Options

The notes in this table come from comments in the source code, which are written in Portuguese.

OptionDefaultWhat for
text''
placement'top-center'
delay350atraso ao apontar: evita piscar ao passar o mouse de raspao
delayOut120
maxWidth'16rem'
className''classe extra no balao, para variar a cor num caso so