R

ReflexKR

Reflex Docs

The Component Workshop: Reflex's 100 Library Components

·

Course overview

Layout

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Typography

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Forms

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Data display

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Disclosure

·

Tabs

·

Accordion

·

Segmented Control

Overlay

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Dynamic rendering

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Media

·

Image

·

Audio

·

Video

Tables and data grids

·

Table

·

Data Table

·

Data Editor

Charts

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Chart parts

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Other chart libraries

·

Plotly

·

Pyplot

HTML elements

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Other tools

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

The Component Workshop: Reflex's 100 Library Components
Overlay

Tooltip

rx.tooltip

Official docs

Workshop order

Our editing toolbar is all icons. Add a short label to each button that tells you what it does when you hover over it.

rx.tooltip is a small label that appears briefly when you hover over an element or move keyboard focus to it. Pass the element to wrap as a child and the text to show in the content prop. Its most common job is naming elements that have no text of their own, such as icon buttons.

rx.tooltip(
    rx.button("Hover over me"),
    content="This is the tooltip content.",
)

Try the props

Most tooltip props are about placement. Change a value, then hover over the button. delay_duration is how long (in milliseconds) the tooltip waits after the pointer arrives before it appears.

Try the props

content

side

align

side_offset

4

delay_duration

700

avoid_collisions

rx.tooltip(
    rx.button("Hover me", variant="soft"),
    content="Save changes",
    side="top",
    align="center",
    side_offset=4,
    delay_duration=700,
    avoid_collisions=True,
)
side picks which side it opens on, align picks where it lines up along that side, and side_offset sets the gap from the button.
PropValuesDefaultUse
contentstring-Text shown in the tooltip
side"top" "right" "bottom" "left""top"Side it opens on
align"start" "center" "end""center"Where it lines up along that side
side_offset · align_offsetnumber (px)-Gap from the element; extra shift from the aligned position
avoid_collisionsTrue / FalseTrueFlip to the opposite side when it hits the edge of the screen
collision_paddingnumber or per-side dict-Margin treated as the edge of the screen
arrow_paddingnumber (px)-Space between the arrow and the corners
sticky"partial" "always""partial"How closely it sticks to the element while scrolling
hide_when_detachedTrue / FalseFalseHide the tooltip when the element is covered
delay_durationmilliseconds700Wait before it appears
disable_hoverable_contentTrue / False-Close even when the pointer moves onto the tooltip
default_openTrue / False-Open on first render (uncontrolled)
openTrue / False-Drive the open state from State (controlled)
force_mountTrue / False-Keep it in the DOM while closed (for animation libraries)
aria_labelstring-Name read by screen readers
on_open_changeevent-Fires on open or close; passes the new open value (bool)
on_escape_key_downevent-Esc is pressed
on_pointer_down_outsideevent-A press lands outside the tooltip

Four sides

side is only a preference. If there is no room on that side, avoid_collisions moves the tooltip to the opposite one.

rx.flex(
    rx.tooltip(rx.button("top", variant="outline"), content="side=top", side="top"),
    rx.tooltip(rx.button("right", variant="outline"), content="side=right", side="right"),
    rx.tooltip(rx.button("bottom", variant="outline"), content="side=bottom", side="bottom"),
    rx.tooltip(rx.button("left", variant="outline"), content="side=left", side="left"),
    spacing="3",
    wrap="wrap",
)

Reacting to open and close: on_open_change

Every time the tooltip opens or closes, on_open_change fires and the handler receives the new open value (True/False). The example below shows how many times that happened and the current state.

Opened or closed: 0 times

Tooltip open: no

class TooltipEventState(rx.State):
    num_opens: int = 0
    opened: bool = False

    @rx.event
    def count_opens(self, value: bool):
        self.opened = value
        self.num_opens += 1


rx.flex(
    rx.text("Opened or closed: ", TooltipEventState.num_opens, " times"),
    rx.text("Tooltip open: ", rx.cond(TooltipEventState.opened, "yes", "no")),
    rx.tooltip(
        rx.button("Hover over me"),
        content="This is the tooltip content.",
        on_open_change=TooltipEventState.count_opens,
    ),
    direction="column",
    spacing="3",
    align="start",
)

Opening and closing from State

Bind open to a State value and your code decides whether the tooltip is open. Wire up on_open_change as well, so opening and closing it with the pointer gets written back to State. Below, you can pin the hint open with the button or open it by hovering over the input.

class TooltipControlState(rx.State):
    show: bool = False

    @rx.event
    def set_show(self, value: bool):
        self.show = value

    @rx.event
    def toggle(self):
        self.show = not self.show


rx.flex(
    rx.tooltip(
        rx.input(placeholder="Coupon code", width="12em"),
        content="Codes are 8 letters, e.g. SPRING24",
        open=TooltipControlState.show,
        on_open_change=TooltipControlState.set_show,
        side="right",
    ),
    rx.button(
        rx.cond(TooltipControlState.show, "Hide hint", "Show hint"),
        on_click=TooltipControlState.toggle,
        variant="soft",
    ),
    spacing="3",
    align="center",
    wrap="wrap",
)

Other props

default_open=True opens the tooltip only at first; after that it follows the pointer as usual. With disable_hoverable_content on, the tooltip closes right away even if you move the pointer onto it. When content is too short to make sense on its own, give screen readers a separate name with aria_label.

rx.flex(
    rx.tooltip(rx.button("default_open"), content="Open on first render", default_open=True, side="bottom"),
    rx.tooltip(rx.button("disable_hoverable_content", variant="soft"), content="Closes as soon as you leave the button",
               disable_hoverable_content=True),
    rx.tooltip(rx.icon_button(rx.icon("info"), variant="ghost"), content="?", aria_label="More information about this field"),
    spacing="3",
    wrap="wrap",
    align="center",
)

Filling the order

Give each icon button a tooltip with its name, and set side="bottom" so they open below the toolbar. Shorten delay_duration too, so there is less waiting as the pointer slides along the bar.

rx.flex(
    rx.tooltip(rx.icon_button(rx.icon("bold"), variant="ghost", aria_label="Bold"), content="Bold (Ctrl+B)", side="bottom", delay_duration=200),
    rx.tooltip(rx.icon_button(rx.icon("italic"), variant="ghost", aria_label="Italic"), content="Italic (Ctrl+I)", side="bottom", delay_duration=200),
    rx.tooltip(rx.icon_button(rx.icon("underline"), variant="ghost", aria_label="Underline"), content="Underline (Ctrl+U)", side="bottom", delay_duration=200),
    rx.separator(orientation="vertical", size="1"),
    rx.tooltip(rx.icon_button(rx.icon("link"), variant="ghost", aria_label="Insert link"), content="Insert link", side="bottom", delay_duration=200),
    spacing="2",
    align="center",
    padding="6px",
    border=f"1px solid {rx.color('gray', 6)}",
    border_radius="8px",
    width="fit-content",
)

Workshop notes

  • rx.tooltip(element, content="text"): appears on hover or focus.

  • Placement is side · align · side_offset; screen edges are handled by avoid_collisions · collision_padding.

  • delay_duration controls how soon it appears (700ms by default).

  • on_open_change passes the new open value (bool). If you control open from State, always wire it up too.

  • A tooltip is a supplementary hint. Put anything people must know, or anything to click, in a Popover or Dialog.

← Previous

Disclosure · Segmented Control

Next →

Overlay · Popover

Get news about new lessons

We'll email you when this course gets new lessons or a follow-up course opens.

We collect: your email address · Purpose: news about new lessons or the launch of this course · Kept until: you ask us to remove it. We never use it for anything else or share it. Reply to any notice email and we'll delete it right away.

Questions & answers

Ask anything about this lesson. Questions from every language version of this page appear together.

Shown as plain text, without links or formatting.

R

ReflexKR

Learn Python and Reflex by doing. Every example was run and verified on Reflex 0.10.0.

ReflexKR is free, with no banner ads. If it helped you, you can support it with a coffee. ☕ Buy us a coffee

Affiliate disclosure
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex