Tooltip

Easily add tooltips to an interactive element or component via the <BTooltip> component or v-b-tooltip directive. Tooltips can also be created and programmatically controlled via the composable usePopover

HTML
template
<div class="d-flex gap-2">
  <BTooltip>
    <template #target> <BButton> Hover Me </BButton></template>
    I am tooltip <b>component</b> content using the <b>#target</b> slot!
  </BTooltip>

  <BButton id="overview-tooltip"> Hover Me </BButton>
  <BTooltip target="overview-tooltip">
    I am tooltip <b>component</b> content using the <b>target</b> prop!
  </BTooltip>

  <BButton v-b-tooltip.focus.top="'I am tooltip directive content!'"> Hover Me </BButton>
</div>

Overview

Things to know when using the tooltip component:

  • Tooltip is a wrapper for Popover, providing a simple way to create tooltips in your application. It uses the same API as Popover, but with some default properties set for tooltips.
    • The delay is zero
    • sideMargin is 0
    • Tooltips are non-interactive by default.
  • Tooltips rely on the 3rd party library floating-ui for positioning.
  • Use teleportTo and teleportDisabled to control where in the DOM the tooltip is rendered. See the Vue.js Docs for details. teleportTo defaults to undefined.
  • Triggering tooltips on hidden elements will not work.
  • Tooltips for disabled elements must be triggered on a wrapper element.
  • When triggered from hyperlinks that span multiple lines, tooltips will be centered. Set the inline prop to improve the positioning. See the Floating UI docs for details.

Target

The target is the trigger element (or component) that will trigger the tooltip. The target is specified via the target slot or prop, and can be any of the following:

The target prop may be any of the following:

  • A string identifying the ID of the trigger element (or ID of the root element of a component)
  • A string with querySelector. (i.e. '#toolbar > div:first-child')
  • A reference (ref) to an HTMLElement or an SVGElement via a Template Ref
  • A reference (ref) to a component that has either an HTMLElement or SVGElement as its root element via Template Ref

NOTE

HTMLElement refers to standard HTML elements such as <div>, <button>, etc., while SVGElement refers to <svg> or supported child elements of SVGs.

Making tooltips work for keyboard and assistive technology users

You should only add tooltips to HTML elements that are traditionally keyboard-focusable and interactive (such as links, buttons, or form controls). Although arbitrary HTML elements (such as <span>s) can be made focusable by adding the tabindex="0" attribute, this will add potentially annoying and confusing tab stops on non-interactive elements for keyboard users. In addition, most assistive technologies currently do not announce the tooltip in this situation.

Additionally, do not rely solely on hover as the trigger for your tooltip, as this will make your tooltips impossible to trigger for keyboard-only users.

Disabled elements

Elements with the disabled attribute aren’t interactive, meaning users cannot focus, hover, or click them to trigger a tooltip (or popover). As a workaround, you’ll want to trigger the tooltip from a wrapper <div> or <span>, ideally made keyboard-focusable using tabindex="0", and override the pointer-events on the disabled element.

Positioning

Twelve static options are available for the placement prop: top, top-start, top-end, bottom, bottom-start, bottom-end, left, left-start, left-end, right, right-start, and right-end from @floating-ui/vue plus three auto placement options auto, auto-start and auto-end.

Positioning is relative to the trigger element.

HTML
template
<BContainer>
  <BRow class="my-2">
    <BCol class="d-grid gap-2">
      <BTooltip placement="top">
        <template #target><BButton>Top</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="top-start">
        <template #target><BButton>Top Start</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="top-end">
        <template #target><BButton>Top End</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
    <BCol class="d-grid gap-2">
      <BTooltip placement="bottom">
        <template #target><BButton>Bottom</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="bottom-start">
        <template #target><BButton>Bottom Start</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="bottom-end">
        <template #target><BButton>Bottom End</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
    <BCol class="d-grid gap-2">
      <BTooltip placement="left">
        <template #target><BButton>Left</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="left-start">
        <template #target><BButton>Left Start</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="left-end">
        <template #target><BButton>Left End</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
    <BCol class="d-grid gap-2">
      <BTooltip placement="right">
        <template #target><BButton>Right</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="right-start">
        <template #target><BButton>Right Start</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
      <BTooltip placement="right-end">
        <template #target><BButton>Right End</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
  </BRow>
</BContainer>
<BContainer>
  <BRow class="my-2">
    <BCol class="d-grid gap-2">
      <BTooltip placement="auto">
        <template #target><BButton>Auto</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
    <BCol class="d-grid gap-2">
      <BTooltip placement="auto-start">
        <template #target><BButton>Auto Start</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
    <BCol class="d-grid gap-2">
      <BTooltip placement="auto-end">
        <template #target><BButton>Auto End</BButton></template>
        I am tooltip <b>component</b> content!
      </BTooltip>
    </BCol>
  </BRow>
</BContainer>

Interactive

BTooltip has an interactive prop, which allows you to set the tooltip to be interactive. This means that the tooltip will remain open when the mouse is over it or focus is within it, allowing users to interact with its content.

HTML
vue
<template>
  <div class="d-flex gap-2">
    <BTooltip interactive>
      <template #target>
        <BButton>Hover me</BButton>
      </template>
      <span class="me-2">{{ count }}</span>
      <BButton @click="count++">+</BButton>
    </BTooltip>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
const count = ref(0)
</script>

Triggers

By default, tooltips are shown by pointerenter and focus events and closed by pointerleave and blur events on the target element. To override this behavior and make the tooltip show and hide based on click events, set the click prop to true.

HTML
template
<div class="d-flex gap-2">
  <BTooltip
    placement="top"
    body="Default Trigger"
  >
    <template #target>
      <BButton> Default Trigger </BButton>
    </template>
  </BTooltip>
  <BTooltip
    click
    placement="top"
    body="Click Trigger"
  >
    <template #target>
      <BButton> Click Trigger </BButton>
    </template>
  </BTooltip>
</div>

To take finer control of tooltip visibility, you can use the useToggle or usePopover. Alternately, you can set the manual prop and use the v-model or exposed functions to control visibility.

Content

The content of a tooltip can be set via the title or body props, or the title or default slots.

NOTE

Unlike popover content which has a separate title and body, tooltips only have one location to place the content. The title prop and slot take precedence over the body and default slot, and the slots (as always) take precedence over the props.

HTML
template
<div class="d-flex gap-2">
  <BTooltip title="Tooltip Title via Property">
    <template #target>
      <BButton variant="primary">Using property</BButton>
    </template>
  </BTooltip>
  <BTooltip>
    <template #target>
      <BButton variant="primary">Using slot</BButton>
    </template>
    Embedding content <span class="text-danger">using slots</span> affords you
    <em>greater <strong>control.</strong></em> and HTML support.
  </BTooltip>
</div>

Custom Classes and Variants

Custom classes can be applied to the tooltip using the title-class prop or body-class prop (depending on which prop or slot you use to populate the tooltip):

template
<div class="d-flex gap-2">
  <BTooltip body-class="my-tooltip-body-class">
    <template #target>
      <BButton
        href="#"
        tabindex="0"
        >Button</BButton
      >
    </template>
    My tooltip
  </BTooltip>
  <BTooltip
    title="My tooltip"
    title-class="my-tooltip-title-class"
  >
    <template #target>
      <BButton
        href="#"
        tabindex="1"
        >Button</BButton
      >
    </template>
  </BTooltip>
</div>

Similarly, use Bootstrap's Color and background utilities to change the variant of the tooltip.

HTML
template
<BTooltip
  title-class="text-bg-danger"
  title="Danger variant tooltip"
>
  <template #target>
    <BButton>Button</BButton>
  </template>
</BTooltip>

body-class and title-class are reactive and can be changed while the tooltip is open.

Refer to the tooltip directive docs on applying custom classes to the directive version.

For finer control, use the bootstrap 5 css variables to apply styles directly.

HTML
template
<BTooltip
  style="--bs-tooltip-color: var(--bs-body-color); --bs-tooltip-bg: var(--bs-danger-bg-subtle)"
>
  <template #target>
    <BButton>Button</BButton>
  </template>
  This is <strong>important</strong>
</BTooltip>

Programmatic control via v-model

You can manually control the visibility of a tooltip via the v-model. Setting it to true will show the tooltip, while setting it to false will hide the tooltip.

Tooltip is hidden

HTML
vue
<template>
  <div class="d-flex flex-column text-md-center">
    <div class="p-2">
      <p>Tooltip is {{ model ? 'visible' : 'hidden' }}</p>
    </div>

    <div class="p-2">
      <BTooltip
        v-model="model"
        placement="right"
      >
        <template #target>
          <BButton
            class="mx-2"
            @click="model = !model"
            >Toggle Tooltip</BButton
          >
        </template>
        Hello <strong>World!</strong>
      </BTooltip>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'

const model = ref(false)
</script>

To make the tooltip show on initial render, simply add prop show to <BTooltip>:

HTML
template
<template>
  <div class="text-center">
    <BTooltip show>
      <template #target>
        <BButton variant="primary">Button</BButton>
      </template>
      I start <strong>open</strong>
    </BTooltip>
  </div>
</template>

Tooltips can also be controlled via Exposed functions.

Close on Hide

The close-on-hide prop can be used to have the tooltip automatically close when the target is scrolled out of view. The boundary and boundary-padding props can be used to control what's considered clipping.

HTML
vue
<template>
  <div class="d-flex gap-2">
    <BTooltip
      :click="true"
      :close-on-hide="true"
      :delay="{show: 0, hide: 0}"
    >
      <template #target>
        <BButton>Click me. Tooltip closes when clipped</BButton>
      </template>
      Scroll me out of view
    </BTooltip>
    <BTooltip
      :click="true"
      :close-on-hide="true"
      :delay="{show: 0, hide: 0}"
      :boundary-padding="{top: navHeight}"
    >
      <template #title>Scroll me out of view</template>
      <template #target>
        <BButton>This tooltip gets hidden by the top nav</BButton>
      </template>
    </BTooltip>
  </div>
</template>

<script setup lang="ts">
import {computed, onMounted, ref} from 'vue'

const navRef = ref<Element | null>(null)
onMounted(() => {
  navRef.value = document.body.querySelector('#app > nav')
})
const navHeight = computed(() => navRef.value?.clientHeight)
</script>

Exposed functions

BTooltip exposes several functions to allow manipulation of the state of the component. These are accessed through the template ref

HTML
vue
<template>
  <div class="d-flex flex-column text-md-center">
    <div class="p-2">
      <BButton
        id="tooltip-expose"
        variant="primary"
        >I have a tooltip</BButton
      >
    </div>

    <div class="p-2">
      <BButton
        class="mx-2"
        @click="show"
        >Show</BButton
      >
      <BButton
        class="mx-2"
        @click="hide"
        >Hide</BButton
      >
      <BButton
        class="mx-2"
        @click="toggle"
        >Toggle</BButton
      >

      <BTooltip
        ref="myTooltip"
        v-model="model"
        target="tooltip-expose"
        title="Tooltip"
      >
        Hello <strong>World!</strong>
      </BTooltip>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
import {BTooltip} from 'bootstrap-vue-next/components/BTooltip'
const myTooltip = ref<InstanceType<typeof BTooltip> | null>(null)
const show = () => myTooltip.value?.show()
const hide = () => myTooltip.value?.hide()
const toggle = () => myTooltip.value?.toggle()
const model = ref(false)
</script>

Component Reference

<BPopover>

PropTypeDefaultDescription
bodystringundefined Text to place in the body of the popover
body-classClassValueundefined CSS class (or classes) to apply to the body
boundaryBoundary | RootBoundary'clippingAncestors' The boundary constraint of the popover: members of `Boundary` and `RootBoundary`.
boundary-paddingPaddingundefined The popover will try and stay away from the edge of the boundary element by the number of pixels specified
clickbooleanfalse show/hide the popover on click of the target element (default is hover/focus)
close-on-hidebooleanfalse When `noAutoClose` is set, this prop will close the popover when the target is hidden
delaynumber | { show: number; hide: number }'() => {show: 100, hide: 300})' Value for the show and hide delay. Applies to both show and hide when specified as a number or string. Use object form to set show and hide delays individually
floating-middlewareMiddleware[]undefined Directly set the floating-ui middleware behavior. See above for details.
focusbooleanundefined Enable/disable focus trigger. See [Triggers](#triggers) for details.
hide-marginnumber0 The margin to apply when hiding the popover on pointer leave (how far the pointer can move off the target before hiding the popover)
hoverbooleanundefined Enable/disable hover trigger. See [Triggers](#triggers) for details.
idstringundefined Used to set the `id` attribute on the rendered content, and used as the base to generate any additional element IDs as needed
initial-animationbooleanfalse When set, enables the initial animation on mount
inlinebooleanfalse Improves positioning for inline reference elements that span over multiple lines (from floating-ui).
interactivebooleanfalse Whether the tooltip is interactive (can be hovered/focused without closing).
lazybooleanfalse When set, the content will not be mounted until opened
manualbooleanfalse Disables all triggers. Use programmatic API to show/hide the popover
model-valuebooleanfalse Controls the visibility of the component
no-animationbooleanfalse When set, disables the animation
no-auto-closebooleanfalse Disables automatic closing on click outside or scroll out of view. Overrides `close-on-hide`
no-fadebooleanfalse Alias for `noAnimation`
no-flipbooleanfalse Disables the automatic flipping of the popover when it goes out of view.
no-hidebooleanfalse Overrides the default behavior of hiding the popover based on boundary & rootBoundary.
no-shiftbooleanfalse Disables the automatic shifting of the popover to keep it in view.
no-sizebooleanfalse Disables the automatic sizing of the popover to fit the clipping region.
noninteractivebooleanfalse Make popover noninteractive. Interactive popover can be hovered/focused without it closing.
offsetNumberish | nullnull Offset of the popover, how many pixels away from the target the popover is. If null it's translated to the size of the arrow in bootstrap css.
placementPopoverPlacement'top' Placement of a floating element
realtimebooleanfalse Whether to update the position of the floating element on every animation frame if required. Very cpu intensive, the default is to listen to browser events.
referencestring | ComponentPublicInstance | HTMLElement | nullnull The reference element to which the popover is anchored. If not specified, the popover will be positioned relative to the target element.
showbooleanfalse When set, and prop 'visible' is false on mount, will animate from closed to open on initial mount. Mainly to help with template show. Use model-value for reactive show/hide
strategyStrategy'absolute'
targetstring | ComponentPublicInstance | HTMLElement | null null The trigger element to invoke the popover as well as the reference element to which the popover is anchored, unless `reference` is defined.
teleport-disabledbooleanfalse Renders the popover in the exact place it was defined
teleport-tostring | RendererElement | null | undefinedundefined Overrides the default teleport location
titlestringundefined Text content to place in the title
title-classClassValueundefined CSS class (or classes) to apply to the title
tooltipbooleanfalse The popover is rendered as a tooltip (used internally by BTooltip)
trans-propsTransitionPropsundefined Transition properties
unmount-lazybooleanfalse When set and `lazy` is true, the content will be unmounted when closed
visiblebooleanfalse When 'true', open without animation
EventArgsDescription
blur
value: BvTriggerableEvent
Emitted when the target element loses focus.
cancel
click-outside
value: BvTriggerableEvent
Emitted when the mouse is clicked outside the popover.
close-on-hide
value: BvTriggerableEvent
Emitted when the popover is closed due to being clipped.
hidden
value: BvTriggerableEvent
Always emits after the component is hidden
hide
value: BvTriggerableEvent - Call value.preventDefault() to cancel hide
Always emits just before the component has hidden. Cancelable (as long as component wasn't forcibly hidden)
hide-prevented
value: BvTriggerableEvent
Emitted when the component tried to close, but was prevented from closing. This occurs when preventDefault() is called on the event, the user clicks escape and no-close-onbackdrop is set to true, or the user clicks on the backdrop and no-close-onbackdrop is set to true.
ok
pointerleave
value: BvTriggerableEvent
Emitted when the pointer leaves the target element, but not when leaving the popover element.
show
value: BvTriggerableEvent - Call value.preventDefault() to cancel show
Always emits just before the component is shown. Cancelable
show-prevented
value: BvTriggerableEvent
Emitted when the component tried to open, but was prevented from opening. This occurs when preventDefault() is called on the event
shown
value: BvTriggerableEvent
Always emits just after component is shown.
toggle
value: BvTriggerableEvent - Call value.preventDefault() to cancel hide
Always emits just before the component is toggled via the exposed 'toggle()' function or useToggle composable . Cancelable (as long as component wasn't forcibly hidden)
toggle-prevented
value: BvTriggerableEvent
Emitted when the component tried to toggle, but was prevented from doing so. This occurs when preventDefault() is called on the event, the user clicks escape and no-close-onbackdrop is set to true, or the user clicks on the backdrop and no-close-onbackdrop is set to true.
update:model-value
value: boolean - New visibility state of the popover.
Emitted when the visibility of the popover changes.
NameScopeDescription
default
id: string - Unique ID for the component
show: () => void - Function to show the component
hide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the component. `trigger` is the trigger that caused the hide. `noTriggerEmit` prevents the emit of the trigger event.
toggle: () => void - Function to toggle the component visibility
active: boolean - Indicates if the component is active (starting show, before/after animations)
visible: boolean - Indicates if the component is visible (shown)
Content for the popover body.
target
id: string - Unique ID for the component
show: () => void - Function to show the component
hide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the component. `trigger` is the trigger that caused the hide. `noTriggerEmit` prevents the emit of the trigger event.
toggle: () => void - Function to toggle the component visibility
active: boolean - Indicates if the component is active (starting show, before/after animations)
visible: boolean - Indicates if the component is visible (shown)
Content for the target or trigger element.
title
id: string - Unique ID for the component
show: () => void - Function to show the component
hide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the component. `trigger` is the trigger that caused the hide. `noTriggerEmit` prevents the emit of the trigger event.
toggle: () => void - Function to toggle the component visibility
active: boolean - Indicates if the component is active (starting show, before/after animations)
visible: boolean - Indicates if the component is visible (shown)
Content for the popover title.