Skip to content

BbTooltip

A short label attached to a control, as a component or as the v-bb-tooltip directive.

import { BbTooltip } from 'bitboss-ui';

On this page

Use it for

Reach for BbTooltip to hang a short label on something the user is already looking at. What an icon-only button does, what a piece of jargon means, the full value behind a truncated cell.

Use something else when

  • BbPopover: the hint holds something to click, or should stay open while the reader works through it
  • BbDropdown: it is a menu of actions

Pass Through

Hover or tap a part to outline it. Toggles flip loading, errors and warnings when the component has them — only parts highlight.

Shortcut hint

A tooltip describes, a popover contains. The bubble never takes focus, so a link or a button inside it is unreachable from a keyboard.

Helpful hints

Keep required guidance visible and use a tooltip for the aside. Pass the label to text, put the trigger in the activator slot, and spread its props.

The name appears in audit logs next to every request this key makes.

The classic pairing is an icon-only button. Keep its aria-label as well: the label names the control, the tooltip describes it. Delete the label because "the tooltip already says it" and the button becomes nameless for a screen reader.

Directive or component

When the label is plain text, use the directive. v-bb-tooltip attaches a tooltip to any element with no wrapper and no slot, which is what makes it the right tool inside a table.

vue
<!-- string shorthand: the value is the label -->
<span v-bb-tooltip="'North Atlantic Treaty Organization'">NATO</span>

<!-- the directive argument sets the placement -->
<BbButton
    v-bb-tooltip:bottom="'Saved automatically'"
    aria-label="Saved"
    icon="lucide:check"
/>

<!-- object form: a required text plus any BbTooltip prop -->
<span
    v-bb-tooltip="{ text: 'Opens after 300ms', placement: 'right', delay: 300 }"
>Hover me</span>

<!-- an empty value attaches nothing, so it is safe to bind conditionally -->
<span v-bb-tooltip="isTruncated ? label : ''">{{ label }}</span>
  • Q2 revenue review.pdf2.4 MB
  • Supplier contract — Aeris.pdf795.8 KB
  • Catalogue export 2026-08.csv144.8 KB
  • Warehouse stock count.xlsx94.5 KB
  • Product photography brief.docx42.1 KB

Escalate to the component only when you need a slot: markup inside the label, or the activator scope to make the trigger react. If it is a string, it is the directive.

The directive runs on mount, so on a prerendered page its label reaches the DOM only after hydration. The component with a text prop renders its description into the server HTML.

The plugin registers the directive globally. Importing vBbTooltip in <script setup> registers it locally instead, which is what the demos on this site do.

Keyboard and assistive technology

Two rules. Break either one and nothing warns you: the page looks finished.

A tooltip needs a focusable trigger. It opens on hover and on :focus-visible. That only helps if the element it hangs off can take focus. A <span> cannot, so put the tooltip on a button, a link or a field. If the trigger really has to be a span, give it a real role and tabindex="0".

A tooltip is never the only home for a fact. Hover text does not exist on a touch screen. It does not print, and it is gone the moment the pointer moves. Anything the user must know to fill the field in correctly belongs in description or hint on the field itself. The tooltip carries the aside.

The truncated cell above is the honest exception: the full value is already a text node in the page, so a screen reader reads it either way.

Placement, timing and width

placement defaults to top and offers the top, right, bottom and left families with -start and -end alignment.

delay (ms, 0 by default) holds the opening back until the pointer settles. On a dense toolbar that is the difference between a hint and five bubbles flashing as the cursor crosses the row. It delays only the open, so it is not a way to keep a tooltip on screen longer.

width caps the bubble in pixels, or as a percentage of the trigger, so a long hint wraps instead of stretching across the viewport.

Labels with markup

The default slot takes markup, which is how an action name gets its keyboard shortcut beside it.

The content stays a description. Everything in the slot is flattened into one string, so a screen reader hears "Search ⌘K" as a single phrase. The rule about interactive content holds here too: markup does not make the bubble focusable, and an <a> in there is unreachable.

Variants and styling

variant tints the bubble: default is the primary bubble and destructive the danger tint. hide-arrow drops the point when it would land on a neighbouring control.

Duplicate this recordDeleting removes every version of this recordVisible to everyone with the link

variant accepts only registered names, so variant="info" does not compile until info is in the plugin config:

ts
// nuxt.config.ts
export default defineNuxtConfig({
    bitboss: { tooltipVariants: ['info'] },
});

Registering a name gets you the type; the CSS is yours. Colour comes from three custom properties on the tooltip root, which the component re-applies to the bubble and the arrow:

css
.bb-tooltip.bb-tooltip--info {
    --bg: var(--bb-panel);
    --fg: var(--bb-text);
    --border-color: var(--bb-border);
}

--fs, --px and --py size the text and its padding on the same root. Derived tokens like --bb-text-muted keep the values they computed against the page, not against the bubble. It is one more reason a tooltip holds text rather than components.

Coming from v2

The v2 theme prop became variant, and it is typed.