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
Workshop order
Give the product card a bold product name, a small gray description and a large, emphasized price.
rx.text is the most basic part for putting words on the screen. It renders a <span> by default, and props set its size, weight, alignment and color. Use it for every piece of text that is not a heading: descriptions, labels, numbers.
The quick brown fox jumps over the lazy dog.
rx.text("The quick brown fox jumps over the lazy dog.")These props decide how the text looks. align only shows when the text is a block that fills the whole line (p, div).
Try the props
The quick brown fox jumps over the lazy dog.
label
as_
size
weight
align
trim
color
high_contrast
rx.text("The quick brown fox jumps over the lazy dog.", as_="p", size="3", weight="regular", align="left", trim="normal", color_scheme="gray", high_contrast=False)| Prop | Values | Default | Use |
|---|---|---|---|
as_ | "p" "label" "div" "span" "b" "i" "u" "abbr" "cite" "del" "em" "ins" "kbd" "mark" "s" "samp" "sub" "sup" | "span" | The HTML tag actually rendered. The look stays the same |
size | "1" ~ "9" | inherited | Font size, line height and letter spacing |
weight | "light" "regular" "medium" "bold" | inherited | Font weight |
align | "left" "center" "right" | inherited | Alignment inside the block |
trim | "normal" "start" "end" "both" | "normal" | Trims the line-height space above and below the text |
color_scheme | Radix color name | theme color | Text color |
high_contrast | True / False | False | Stronger contrast against the background |
as_child | True / False | False | Uses the child element as is and only applies the text styles |
size, weight, align and trim also accept per-breakpoint values ({"initial": "2", "md": "4"}). The only events are the standard ones such as on_click.
as_ only changes which tag is rendered. The four lines below are a p, a label, a div and a span, yet they look the same. Pick the tag that matches the meaning, p for a paragraph, label for the name of an input, and screen readers and search engines understand the content better.
This is a paragraph element.
rx.flex(
rx.text("This is a ", rx.text.strong("paragraph"), " element.", as_="p"),
rx.text("This is a ", rx.text.strong("label"), " element.", as_="label"),
rx.text("This is a ", rx.text.strong("div"), " element.", as_="div"),
rx.text("This is a ", rx.text.strong("span"), " element.", as_="span"),
direction="column",
spacing="3",
)size sets more than the font size: it tunes line height and letter spacing too. The larger the text, the tighter the relative line height and letter spacing. Sizes 2 to 4 suit long body text; 1 to 3 suit UI text such as a label next to a button.
Size 1: captions and hints
Size 2: UI labels
Size 3: body text
Size 5: lead paragraph
Size 7: big numbers
Size 9: hero
rx.flex(
rx.text("Size 1: captions and hints", size="1"),
rx.text("Size 2: UI labels", size="2"),
rx.text("Size 3: body text", size="3"),
rx.text("Size 5: lead paragraph", size="5"),
rx.text("Size 7: big numbers", size="7"),
rx.text("Size 9: hero", size="9"),
direction="column",
spacing="3",
)rx.flex(
rx.text("Light", weight="light", as_="div"),
rx.text("Regular", weight="regular", as_="div"),
rx.text("Medium", weight="medium", as_="div"),
rx.text("Bold", weight="bold", as_="div"),
rx.separator(),
rx.text("Left-aligned", align="left", as_="div"),
rx.text("Center-aligned", align="center", as_="div"),
rx.text("Right-aligned", align="right", as_="div"),
direction="column",
spacing="3",
width="100%",
)Text carries invisible space above and below it, as tall as its line height. That is why the same padding looks wider at the top and bottom than at the sides. trim cuts that space away: "start" at the top, "end" at the bottom, "both" on both sides. The difference is easiest to see in a bordered box such as a card.
Typography relates font size, line height and line width.
Typography relates font size, line height and line width.
rx.flex(
rx.box(
rx.heading("Without trim", as_="h2", size="3", margin_bottom="4px"),
rx.text("Typography relates font size, line height and line width."),
padding="16px",
style={"background": "var(--gray-a2)", "border": "1px dashed var(--gray-a7)"},
),
rx.box(
rx.heading("With trim", as_="h2", size="3", margin_bottom="4px", trim="start"),
rx.text("Typography relates font size, line height and line width.", trim="end"),
padding="16px",
style={"background": "var(--gray-a2)", "border": "1px dashed var(--gray-a7)"},
),
direction="column",
spacing="3",
)color_scheme swaps the theme's accent color for the one you name. Add high_contrast=True and you get a darker shade of the same color that stands out more from the background. The left column is the default, the right column is high contrast.
indigo
indigo
crimson
crimson
orange
orange
rx.grid(
rx.text("indigo", color_scheme="indigo"),
rx.text("indigo", color_scheme="indigo", high_contrast=True),
rx.text("crimson", color_scheme="crimson"),
rx.text("crimson", color_scheme="crimson", high_contrast=True),
rx.text("orange", color_scheme="orange"),
rx.text("orange", color_scheme="orange", high_contrast=True),
columns="2",
spacing="2",
)Put strings together with rx.link, rx.text.em, rx.code and rx.text.kbd as children of rx.text, and only those parts of the sentence look different.
Browsers collapse consecutive spaces into one. When the spaces must stay, add the CSS prop white_space="pre". Compare the second and third lines below.
Look, such a helpful link, an italic emphasis, a piece of computer code, and a hotkey Shift + A within the text.
This is not pre formatted
This is pre formatted
rx.flex(
rx.text(
"Look, such a helpful ",
rx.link("link", href="#"),
", an ",
rx.text.em("italic emphasis"),
", a piece of computer ",
rx.code("code"),
", and a hotkey ",
rx.text.kbd("Shift + A"),
" within the text.",
size="4",
),
rx.text("This is not pre formatted"),
rx.text("This is pre formatted", white_space="pre"),
direction="column",
spacing="3",
)Put a checkbox, radio or switch inside an rx.text with as_="label" and the control lines up with the first line of text, even when the text wraps over several lines. Because it is a label, clicking the text toggles the checkbox too.
rx.box(
rx.text(
rx.flex(
rx.checkbox(default_checked=True),
"I understand that these documents are confidential and cannot be shared with a third party.",
spacing="2",
),
as_="label",
size="3",
),
max_width="300px",
)Split the card into three levels: a bold name, a small gray description and a large colored price. Give the text at the top and bottom edges of the card a trim so the spacing comes out even.
Linen Shirt
Breathable linen, relaxed fit. Machine washable.
$49.00
rx.card(
rx.flex(
rx.text("Linen Shirt", size="4", weight="bold", trim="start"),
rx.text("Breathable linen, relaxed fit. Machine washable.", size="2", color_scheme="gray"),
rx.text("$49.00", size="6", weight="bold", color_scheme="indigo", trim="end"),
direction="column",
spacing="2",
),
max_width="320px",
)Workshop notes
rx.text is a span by default. Use as_ to pick a tag that fits the meaning: p, label, div and so on (the look stays the same).
size "1" to "9" also tunes line height and letter spacing. Body text 2 to 4, UI labels 1 to 3.
align only shows on blocks such as p or div. trim evens out the space above and below inside a box.
color_scheme sets the color, high_contrast the contrast. Keep spaces with white_space="pre".
Mix rx.link, rx.code, rx.text.em and rx.text.kbd in as children to style parts of one sentence.
Get news about new lessons
We'll email you when this course gets new lessons or a follow-up course opens.
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© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Questions & answers
Ask anything about this lesson. Questions from every language version of this page appear together.