Skip to main content
The Tooltip component displays brief, contextual information when hovering over or focusing on an element.

Basic Usage

import reflex_ui as ui

ui.tooltip(
    ui.button("Hover me"),
    content="This is a helpful tooltip"
)

Props Reference

trigger
Component
required
The first argument: element that triggers the tooltip
content
str | Component
required
Text or component to display in the tooltip

Real Example

From demo at demo/demo.py:19:
ui.tooltip(
    ui.button(
        ui.icon("SmileIcon"),
        "Click me",
        on_click=rx.toast.success(
            "You are cool :)",
            position="top-center"
        )
    ),
    content="Seriously, click me"
)

Positioning

side
Literal['top', 'right', 'bottom', 'left', 'inline-start', 'inline-end']
default:"top"
Which side of the trigger to position the tooltip
align
Literal['start', 'center', 'end']
default:"center"
How to align the tooltip relative to the trigger
side_offset
int
default:"8"
Distance between trigger and tooltip in pixels
ui.tooltip(
    ui.button("Info"),
    content="Appears on the right",
    side="right",
    align="start"
)

Timing

delay
int
default:"0"
Delay before showing tooltip on hover (milliseconds)
close_delay
int
default:"0"
Delay before hiding tooltip after hover ends (milliseconds)
ui.tooltip(
    ui.button("Delayed"),
    content="Appears after 500ms",
    delay=500,
    close_delay=200
)

Controlled State

class State(rx.State):
    tooltip_open: bool = False

ui.tooltip(
    ui.button("Controlled"),
    content="Controlled tooltip",
    open=State.tooltip_open,
    on_open_change=State.set_tooltip_open
)
open
bool | Var[bool]
Whether tooltip is visible (controlled)
default_open
bool
default:"False"
Initial visibility (uncontrolled)
on_open_change
EventHandler[bool]
Event fired when tooltip shows or hides
on_open_change_complete
EventHandler[bool]
Event fired after animation completes

Disabled

disabled
bool
default:"False"
Prevents tooltip from showing
ui.tooltip(
    ui.button("No tooltip"),
    content="Won't show",
    disabled=True
)

Cursor Tracking

track_cursor_axis
Literal['none', 'x', 'y', 'both']
default:"none"
Makes tooltip follow the cursor on specified axis
ui.tooltip(
    ui.button("Follows cursor"),
    content="I follow your mouse!",
    track_cursor_axis="both"
)

Hoverable Content

disable_hoverable_popup
bool
default:"True"
When True, tooltip closes when pointer leaves trigger (even if moving to tooltip)
ui.tooltip(
    ui.button("Interactive"),
    content=ui.button("Clickable inside tooltip"),
    disable_hoverable_popup=False
)

Compositional API

For advanced use cases:
ui.tooltip.root(
    ui.tooltip.trigger(
        render_=ui.button("Info", size="icon-sm")
    ),
    ui.tooltip.portal(
        ui.tooltip.positioner(
            ui.tooltip.popup(
                ui.tooltip.arrow(arrow_svg()),
                "Custom tooltip content"
            ),
            side="bottom"
        )
    )
)

Tooltip Components

tooltip.root

Container for all tooltip parts.
ui.tooltip.root(
    # child components
    disabled=False
)

tooltip.trigger

Element that triggers the tooltip.
ui.tooltip.trigger(
    render_=ui.icon("HelpCircle"),
    delay=300
)

tooltip.portal

Portals tooltip to document body.
ui.tooltip.portal(
    ui.tooltip.positioner(...),
    keep_mounted=True
)

tooltip.positioner

Positions the tooltip.
ui.tooltip.positioner(
    ui.tooltip.popup(...),
    side="top",
    side_offset=8
)

tooltip.popup

Tooltip content container.
ui.tooltip.popup(
    "Tooltip text"
)

tooltip.arrow

Arrow pointing to trigger.
ui.tooltip.arrow(arrow_svg())  # Auto-included in high-level API

tooltip.provider

Global configuration for nested tooltips.
ui.tooltip.provider(
    # your app content with tooltips
    delay=300,
    timeout=400
)

Styling Classes

Access predefined styles via ui.tooltip.class_names:
  • TRIGGER: Inline flex layout
  • POPUP: Rounded container with dark background and white text
  • ARROW: Positioned arrow with rotation

Animation

Smooth scale and opacity transitions:
  • Scales from 90% to 100%
  • Fades from 0 to 1 opacity
  • 150ms transition duration

Collision Handling

collision_padding
int
default:"5"
Minimum distance from viewport edges
sticky
bool
default:"False"
Keep tooltip visible after trigger scrolls out of view

Global Provider

Wrap your app to configure all tooltips:
ui.tooltip.provider(
    your_app_component(),
    delay=200,  # Default delay for all tooltips
    close_delay=100,  # Default close delay
    timeout=400  # Time to keep instant-open active
)
timeout
int
default:"400"
Duration where subsequent tooltips open instantly (milliseconds)

Accessibility

  • Keyboard accessible (shows on focus, hides on blur/escape)
  • ARIA attributes
  • Screen reader support
  • Proper role semantics
  • Respects prefers-reduced-motion

Best Practices

  • Keep content brief (1-2 short sentences)
  • Don’t put interactive content in tooltips (use Popover instead)
  • Ensure tooltips don’t hide critical information
  • Test with keyboard navigation
  • Avoid tooltips on mobile (no hover state)

Implementation Details

From source code at reflex_ui/components/base/tooltip.py:214:
  • Built on Base UI Tooltip primitives
  • High-level API takes trigger as first argument, content as second
  • Default side_offset of 8px
  • Default delays set to 0 for instant show/hide
  • Auto-includes arrow SVG
  • Hoverable popup disabled by default
  • Dark background with white text styling

Build docs developers (and LLMs) love