twbs/bootstrap · error · Error

Please use show on visible elements

Error message

Please use show on visible elements

What it means

Tooltip.show() opens with a hard precondition: the trigger element must not carry an inline display:none, because Popper cannot measure a hidden element to position the tip — hence a plain Error, not a TypeError. The check reads this._element.style.display only, before the content/enabled checks and before any show event fires. The hover/focus Data API practically never hits it because a display:none element cannot be hovered; it bites on programmatic show() calls.

Source

Thrown at js/src/tooltip.js:186

    this._enter()
  }

  dispose() {
    clearTimeout(this._timeout)

    EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)

    if (this._element.getAttribute('data-bs-original-title')) {
      this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))
    }

    this._disposePopper()
    super.dispose()
  }

  show() {
    if (this._element.style.display === 'none') {
      throw new Error('Please use show on visible elements')
    }

    if (!(this._isWithContent() && this._isEnabled)) {
      return
    }

    const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))
    const shadowRoot = findShadowRoot(this._element)
    const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)

    if (showEvent.defaultPrevented || !isInTheDom) {
      return
    }

    // TODO: v6 remove this or make it optional
    this._disposePopper()

    const tip = this._getTipElement()

View on GitHub (pinned to 6177d5f849)

Solutions

  1. Remove the inline display:none from the trigger element before calling show().
  2. Defer show() until visibility is real — e.g. inside shown.bs.modal / shown.bs.collapse handlers or after your own reveal transition.
  3. Guard the call: if (el.style.display !== 'none') tip.show().
  4. If the element must stay display:none, attach the tooltip to a visible wrapper element instead.

Example fix

// before — el has style="display: none"
const tip = bootstrap.Tooltip.getOrCreateInstance(el)
tip.show() // Error: Please use show on visible elements

// after — make the trigger visible first
el.style.display = ''
tip.show()
Defensive patterns

Strategy: validation

Validate before calling

const canShowTooltip = (el) => el.style.display !== 'none'

const tip = bootstrap.Tooltip.getOrCreateInstance(el)
if (canShowTooltip(el)) {
  tip.show()
} else {
  console.warn('Tooltip: trigger is display:none — skipping show()')
}

Try / catch

try {
  tip.show()
} catch (err) {
  if (err instanceof Error && err.message === 'Please use show on visible elements') {
    // element hidden by app state: reveal it first, or attach the tooltip to a visible wrapper
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: tip.show() on an element with style="display: none" (hidden until first AJAX completes, onboarding pointers, collapsed panels); calling show() in a loop over a mixed list where some triggers are hidden; showing a tooltip for a button inside a template kept with inline display:none; calling show() from a timer that races with code that sets el.style.display = 'none'.

Common situations: Tooltips on elements revealed by app state (hidden tabs, gated features); scheduled/deferred show() calls; wrapper components that mount tooltips on conditionally rendered DOM; migration from v4 — the same guard existed there, so old hidden-element workarounds resurface.

Related errors


AI-assisted analysis of twbs/bootstrap@6177d5f849 (2026-08-22). Data as JSON: /api/errors/dff5362df844e9c6. Report an issue: GitHub.