Skip to content

Documentation

On this page

Tooltip

Hover and focus tips. aria-description is the no-script fallback. popover="hint" puts the bubble in the top layer; interestfor opens it on hover, focus, or long-press — no Tooltip plugin and no Popper.

Sizes are minified and gzip. A plugin figure includes the Bootstrap runtime that plugin imports. Shipping every plugin is bootstrap.bundle.min.js at 23.3 KB gzip, not the sum of these rows.
What runs it JavaScript
Bootstrap 5.3 Tooltip plugin, including Popper 15.3 KB gzip
This repo aria-description and CSS generated content, or popover=hint. No Popper. 0 KB

When that API is missing, this page also loads interestfor.js (2.8 KB gzip). See Polyfills.

Markup this component accepts. The full inventory is /components.json.
Avoid
  • Do not set role="tooltip" or aria-describedby on an interestfor trigger. Native interestfor associates the target; the polyfill sets aria-describedby (plain hint) or aria-details (rich).
  • interestfor is valid on <a>, <button>, and <area> only.
  • Do not put aria-description and interestfor on the same control (Chromium would announce both).
  • The CSS fallback is plain text. Markup needs a hint popover.

How it works

  • Two markup paths. Use one per trigger: either aria-description plus a .bs-tooltip-* class on the control, or interestfor pointing at a .tooltip with popover="hint". Do not put both on the same control — Chromium would announce the description twice.
  • Add .bs-tooltip-top, .bs-tooltip-end, .bs-tooltip-bottom, or .bs-tooltip-start instead of data-bs-placement. Default placement is top, matching Bootstrap.
  • A hint popover is a separate hint stack: it does not close an open popover="auto" dropdown. Escape dismisses interest.
  • Keep tooltips on keyboard-focusable, interactive elements (links and form controls), as Bootstrap’s docs recommend. interestfor is valid on <a>, <button>, and <area> only.
  • Do not set role="tooltip" or aria-describedby on an interestfor trigger. The browser associates the hint target itself.

No-script fallback

aria-description replaces data-bs-title / title. The bubble is ::after (content: attr(aria-description)) and the arrow is ::before, positioned against the trigger. Hover and keyboard focus (:hover / :focus-within) replace Bootstrap’s default trigger: 'hover focus'. Empty aria-description values never display. The bubble is not in the top layer, so a transformed or overflow-clipped ancestor can still cover it.

Tooltips on links

Hover over the links below to see tooltips.

Placeholder text to demonstrate some inline links with tooltips. Content placed here just to mimic the presence of real text. The same pattern works for further links once the class and description sit on the trigger.

HTML
<p class="text-body-secondary mb-0">Placeholder text to demonstrate some <a href="#" class="bs-tooltip-top text-nowrap" aria-description="Default tooltip">inline links</a> with tooltips. Content placed here just to mimic the presence of <a href="#" class="bs-tooltip-top text-nowrap" aria-description="Another tooltip">real text</a>. The same pattern works for <a href="#" class="bs-tooltip-top text-nowrap" aria-description="Another one here too">further links</a> once the class and description sit on <a href="#" class="bs-tooltip-top text-nowrap" aria-description="The last tip">the trigger</a>.</p>

Custom tooltips

Customize appearance with CSS variables on a class on the trigger (Bootstrap’s data-bs-custom-class injected that class from JS).

HTML
<button type="button" class="btn btn-secondary bs-tooltip-top custom-tooltip" aria-description="This top tooltip is themed via CSS variables.">
  Custom tooltip
</button>

Directions

Four options are available: top, right, bottom, and left. Directions are mirrored when using Bootstrap in RTL. Add .bs-tooltip-top, .bs-tooltip-end, .bs-tooltip-bottom, or .bs-tooltip-start.

HTML
<div class="d-flex flex-wrap justify-content-center gap-2 py-4">
  <button type="button" class="btn btn-secondary bs-tooltip-top" aria-description="Tooltip on top">
    Tooltip on top
  </button>
  <button type="button" class="btn btn-secondary bs-tooltip-end" aria-description="Tooltip on right">
    Tooltip on right
  </button>
  <button type="button" class="btn btn-secondary bs-tooltip-bottom" aria-description="Tooltip on bottom">
    Tooltip on bottom
  </button>
  <button type="button" class="btn btn-secondary bs-tooltip-start" aria-description="Tooltip on left">
    Tooltip on left
  </button>
</div>

Tooltip with HTML

Bootstrap’s data-bs-html can put markup in the bubble. The CSS fallback cannot.

HTML
<button type="button" class="btn btn-secondary bs-tooltip-top" aria-description="Tooltip with HTML">
  Tooltip with HTML
</button>

Disabled elements

Elements with the disabled attribute aren’t interactive, so the tooltip lives on a keyboard-focusable wrapper.

HTML
<span class="d-inline-block bs-tooltip-top" tabindex="0" aria-description="Disabled tooltip">
  <button class="btn btn-primary" type="button" disabled>Disabled button</button>
</span>

Hint popover

The bubble is a .tooltip with popover="hint" and real .tooltip-inner markup. Put interestfor on the trigger, matching the bubble’s id. CSS Anchor Positioning tethers it to that invoker. Hover, keyboard focus, and long-press replace Bootstrap’s trigger: 'hover focus'.

Four directions

Same four placements as the CSS fallback, now in the top layer. Hover or focus the buttons.

Tooltip on top
Tooltip on right
Tooltip on bottom
Tooltip on left
HTML
<div class="d-flex flex-wrap justify-content-center gap-2 py-4">
  <span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintTop">
    Tooltip on top
  </button>
  <div class="tooltip bs-tooltip-top" popover="hint" id="tipHintTop">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Tooltip on top</div>
  </div>
</span>
  <span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintEnd">
    Tooltip on right
  </button>
  <div class="tooltip bs-tooltip-end" popover="hint" id="tipHintEnd">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Tooltip on right</div>
  </div>
</span>
  <span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintBottom">
    Tooltip on bottom
  </button>
  <div class="tooltip bs-tooltip-bottom" popover="hint" id="tipHintBottom">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Tooltip on bottom</div>
  </div>
</span>
  <span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintStart">
    Tooltip on left
  </button>
  <div class="tooltip bs-tooltip-start" popover="hint" id="tipHintStart">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Tooltip on left</div>
  </div>
</span>
</div>

Auto placement

.bs-tooltip-auto still defaults to top. On a hint popover, position-try-fallbacks flips the bubble when it would overflow. The arrow stays in the top orientation after a flip.

Auto tooltip. It flips when there is no room.
HTML
<span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintAuto">
    Tooltip auto
  </button>
  <div class="tooltip bs-tooltip-auto" popover="hint" id="tipHintAuto">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Auto tooltip. It flips when there is no room.</div>
  </div>
</span>

Custom hint tooltips

Put the custom class on the .tooltip element so the CSS variables apply to the bubble.

This top tooltip is themed via CSS variables.
HTML
<span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintCustom">
    Custom tooltip
  </button>
  <div class="tooltip bs-tooltip-top custom-tooltip" popover="hint" id="tipHintCustom">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">This top tooltip is themed via CSS variables.</div>
  </div>
</span>

Hint tooltip with HTML

The inner is markup, so em, u, and b work. That replaces data-bs-html.

Tooltip with HTML
HTML
<span class="d-inline-block">
  <button type="button" class="btn btn-secondary" interestfor="tipHintHtml">
    Tooltip with HTML
  </button>
  <div class="tooltip bs-tooltip-top" popover="hint" id="tipHintHtml">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner"><em>Tooltip</em> <u>with</u> <b>HTML</b></div>
  </div>
</span>

Delay

interest-delay-start and interest-delay-end on the trigger replace data-bs-delay. Hint triggers default to 0s so they match Bootstrap’s delay: 0. The polyfill reads --interest-delay-start / --interest-delay-end; hint CSS sets both. Override --bs-tooltip-delay-start / --bs-tooltip-delay-end on the trigger.

Shows after 500 ms, hides after 150 ms.
HTML
<span class="d-inline-block">
  <button type="button" class="btn btn-secondary" style="--bs-tooltip-delay-start: .5s; --bs-tooltip-delay-end: .15s" interestfor="tipHintDelay">
    Delayed tooltip
  </button>
  <div class="tooltip bs-tooltip-top" popover="hint" id="tipHintDelay">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Shows after 500 ms, hides after 150 ms.</div>
  </div>
</span>

Hint on links

interestfor is valid on a, not only button.

Placeholder text to demonstrate some inline links with hint tooltips. Content placed here just to mimic the presence of real text. Default tooltip Another tooltip

HTML
<p class="text-body-secondary mb-0">Placeholder text to demonstrate some <a href="#" interestfor="tipHintLink1">inline links</a> with hint tooltips. Content placed here just to mimic the presence of <a href="#" interestfor="tipHintLink2">real text</a>.
  <span class="tooltip bs-tooltip-top" popover="hint" id="tipHintLink1">
    <span class="tooltip-arrow"></span>
    <span class="tooltip-inner">Default tooltip</span>
  </span>
  <span class="tooltip bs-tooltip-top" popover="hint" id="tipHintLink2">
    <span class="tooltip-arrow"></span>
    <span class="tooltip-inner">Another tooltip</span>
  </span>
</p>

Disabled hint trigger

interestfor needs a button or a link. Wrap a visually disabled .btn.disabled in a transparent button.

Disabled tooltip
HTML
<span class="d-inline-block">
  <button type="button" class="border-0 bg-transparent p-0" interestfor="tipHintDisabled">
    <span class="btn btn-primary disabled">Disabled button</span>
  </button>
  <div class="tooltip bs-tooltip-top" popover="hint" id="tipHintDisabled">
    <div class="tooltip-arrow"></div>
    <div class="tooltip-inner">Disabled tooltip</div>
  </div>
</span>

Accessibility

aria-description is a description, not the accessible name. Give icon-only controls a name (aria-label or visible text) and use the description for extra help.

The CSS fallback bubble is generated content with empty alternative text, so assistive technology is not read a second copy. Hover and :focus-within show it. It is not in the top layer.

Native interestfor gives a hint popover an implicit tooltip role. The polyfill sets aria-describedby on a plain hint. Escape dismisses interest. The pointer can move onto the bubble (WCAG 1.4.13). Do not add role="tooltip" yourself on the native path.

Browser support

Three columns, not one baseline. The same row is on the overview.
No script Polyfill No fallback
aria-description and content: attr(). Hover and focus. Plain text, not in the top layer. interestfor when interestForElement is missing and the page has [interestfor]. It does not polyfill popover="hint". popover="hint" is Chrome 151+, Firefox 153+, Safari preview. Without hint the polyfill cannot open the top-layer bubble. .bs-tooltip-auto on a hint popover flips with position-try-fallbacks. The arrow stays in the default (top) orientation after a flip.