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

Hover Card

rx.hover_card.rootrx.hover_card.triggerrx.hover_card.content

Official docs

Workshop order

When someone hovers over an author's name on a comment, show a small card with that person's photo and bio.

rx.hover_card is a card that pops up when you hover over an element such as a link. It is bigger than a tooltip and is meant for previews with rich content, such as a photo or several lines of text. It is built from three parts.

  • hover_card.root: wraps all the parts of the hover card.
  • hover_card.trigger: wraps the element (usually a link) that opens the card on hover.
  • hover_card.content: the content shown when it is open.

Hover over the text to see the card. Hover over me

rx.text(
    "Hover over the text to see the card. ",
    rx.hover_card.root(
        rx.hover_card.trigger(
            rx.link("Hover over me", color_scheme="blue", underline="always"),
        ),
        rx.hover_card.content(
            rx.text("This is the hovercard content."),
        ),
    ),
)

Try the props

Placement and size go on hover_card.content. Change a value, then hover over the link.

Try the props

text

side

align

size

avoid_collisions

rx.hover_card.root(
    rx.hover_card.trigger(rx.link("Hover over me", underline="always")),
    rx.hover_card.content(
        rx.text("Preview of the linked page"),
        side="bottom",
        align="center",
        size="2",
        avoid_collisions=True,
    ),
)
size sets the padding, from "1" to "3". By default it opens below (bottom), centered (center).
PartPropValuesUse
rootopen_delaymilliseconds (int)Wait after the pointer arrives before opening
rootclose_delaymilliseconds (int)Wait after the pointer leaves before closing
rootopen · default_openTrue / FalseDrive the open state from State (controlled) · open at first (uncontrolled)
rooton_open_changeeventFires on open or close; passes the new open value (bool)
contentside · alignposition nameSide it opens on and where it lines up
contentside_offset · align_offsetint (px)Gap from the link; extra shift from the aligned position
contentsize"1" "2" "3"Padding size
contentavoid_collisions · collision_paddingbool · numberMove away from the screen edge, and the margin for that
contentsticky · hide_when_detached"partial" "always" · boolHow closely it sticks while scrolling; hide when the link is covered

trigger and content only have the common events; neither defines events of its own.

Rich content

Content can hold grids and images too. rx.inset(side="left") runs the image to the card's left edge, with a title and description on the right. Set the card width directly on content, as in style={"width": 360}.

Hover over the text to see the card. Hover over me

rx.text(
    "Hover over the text to see the card. ",
    rx.hover_card.root(
        rx.hover_card.trigger(
            rx.link("Hover over me", color_scheme="blue", underline="always"),
        ),
        rx.hover_card.content(
            rx.grid(
                rx.inset(
                    side="left",
                    pr="current",
                    background="url('https://picsum.photos/id/1062/240/320') center/cover",
                    height="full",
                ),
                rx.box(
                    rx.heading("Kitsune", size="3"),
                    rx.text("A curious fox who lives in the workshop and inspects every new part.", size="2"),
                    padding_left="12px",
                ),
                columns="120px 1fr",
            ),
            style={"width": 360},
        ),
    ),
)

Timing: open_delay and close_delay

A card that pops up whenever the pointer merely passes by is annoying. open_delay sets how long to wait before opening, and close_delay how long before closing, in milliseconds. Hover over the two links one after the other to feel the difference.

rx.flex(
    rx.hover_card.root(
        rx.hover_card.trigger(rx.link("Fast (open_delay=100)", underline="always")),
        rx.hover_card.content(rx.text("Opened after 100 ms")),
        open_delay=100,
        close_delay=100,
    ),
    rx.hover_card.root(
        rx.hover_card.trigger(rx.link("Slow (open_delay=1200)", underline="always")),
        rx.hover_card.content(rx.text("Opened after 1200 ms")),
        open_delay=1200,
        close_delay=600,
    ),
    spacing="5",
    wrap="wrap",
)

Reacting to open and close: on_open_change

The on_open_change of hover_card.root passes True when it opens and False when it closes.

Opened or closed: 0 times

Hover card open: no

Hover over the text to see the hover card. Hover over me

class HoverCardEventState(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: ", HoverCardEventState.num_opens, " times"),
    rx.text("Hover card open: ", rx.cond(HoverCardEventState.opened, "yes", "no")),
    rx.text(
        "Hover over the text to see the hover card. ",
        rx.hover_card.root(
            rx.hover_card.trigger(
                rx.link("Hover over me", color_scheme="blue", underline="always"),
            ),
            rx.hover_card.content(
                rx.text("This is the hover card content."),
            ),
            on_open_change=HoverCardEventState.count_opens,
        ),
    ),
    direction="column",
    spacing="3",
)

Opening and closing from State

Bind open to a State value and a switch can keep the card open. Because on_open_change is wired to the same handler, the switch also moves when you hover over the link and move away.

class HoverCardControlState(rx.State):
    pinned: bool = False

    @rx.event
    def set_pinned(self, value: bool):
        self.pinned = value


rx.flex(
    rx.hover_card.root(
        rx.hover_card.trigger(rx.link("Release notes", underline="always")),
        rx.hover_card.content(rx.text("v2.4: faster search, new export button.", size="2")),
        open=HoverCardControlState.pinned,
        on_open_change=HoverCardControlState.set_pinned,
    ),
    rx.switch(checked=HoverCardControlState.pinned, on_change=HoverCardControlState.set_pinned),
    rx.text("open", size="2", color_scheme="gray"),
    spacing="3",
    align="center",
)

Filling the order

Hovering over the author's name link shows a card with an avatar, name and bio. Raise open_delay a little so the card does not pop up for a pointer that is just passing through.

Great tutorial! — @mina

rx.text(
    "Great tutorial! — ",
    rx.hover_card.root(
        rx.hover_card.trigger(rx.link("@mina", weight="bold")),
        rx.hover_card.content(
            rx.flex(
                rx.avatar(src="https://picsum.photos/id/64/120/120", fallback="MK", size="4", radius="full"),
                rx.box(
                    rx.heading("Mina Kim", size="3"),
                    rx.text("@mina", size="2", color_scheme="gray"),
                    rx.text("Frontend developer. Writes about Python web apps.", size="2", margin_top="6px"),
                ),
                spacing="3",
            ),
            side="top",
            align="start",
            style={"width": 300},
        ),
        open_delay=400,
    ),
    size="2",
)

Workshop notes

  • Three parts: root · trigger · content. It opens on hover and closes when the pointer leaves (no click needed).

  • open_delay · close_delay (milliseconds, int) keep it from reacting to a passing pointer.

  • Placement and size go on content (side, align, side_offset, size "1"~"3").

  • on_open_change passes the new open value (bool). If you control it with open, wire both up.

  • It never opens on touch screens without a pointer, so keep anything essential on the linked page as well.

← Previous

Overlay · Popover

Next →

Overlay · Dialog

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