Back to Reflex

Theming

docs/styling/theming.md

0.9.215.7 KB
Original Source
python
import reflex as rx

cell_style = {
    "font_family": "Instrument Sans",
    "font_style": "normal",
    "font_weight": "500",
    "font_size": "14px",
    "line_height": "1.5",
    "letter_spacing": "-0.0125em",
    "color": "var(--c-slate-11)",
}

Theming

As of Reflex v0.4.0, you can now theme your Reflex applications. The core of our theming system is directly based on the Radix Themes library. This allows you to easily change the theme of your application along with providing a default light and dark theme. Themes cause all the components to have a unified color appearance.

Overview

The Theme component is used to change the theme of the application. The Theme can be set directly in your rx.App.

python
app = rx.App(
    theme=rx.theme(
        appearance="light", has_background=True, radius="large", accent_color="teal"
    )
)

Here are the props that can be passed to the rx.theme component:

python
rx.table.root(
    rx.table.header(
        rx.table.row(
            rx.table.column_header_cell("Name", class_name="table-header"),
            rx.table.column_header_cell("Type", class_name="table-header"),
            rx.table.column_header_cell("Description", class_name="table-header"),
        ),
    ),
    rx.table.body(
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "has_background",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    "Bool",
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "Whether to apply the themes background color to the theme node. Defaults to True.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "appearance",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    '"inherit" | "light" | "dark"',
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "The appearance of the theme. Can be 'light' or 'dark'. Defaults to 'light'.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "accent_color",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    "Str",
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "The primary color used for default buttons, typography, backgrounds, etc.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "gray_color",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    "Str",
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "The secondary color used for default buttons, typography, backgrounds, etc.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "panel_background",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    '"solid" | "translucent"',
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                'Whether panel backgrounds are translucent: "solid" | "translucent" (default).',
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "radius",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    '"none" | "small" | "medium" | "large" | "full"',
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                )
            ),
            rx.table.cell(
                "The radius of the theme. Can be 'small', 'medium', or 'large'. Defaults to 'medium'.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "scaling",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    '"90%" | "95%" | "100%" | "105%" | "110%"',
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell("Scale of all theme items.", style=cell_style),
        ),
    ),
    variant="surface",
    margin_y="1em",
)

Additionally you can modify the theme of your app through using the Theme Panel component which can be found in the Theme Panel docs.

Colors

Color Scheme

On a high-level, component color_scheme inherits from the color specified in the theme. This means that if you change the theme, the color of the component will also change. Available colors can be found here.

You can also specify the color_scheme prop.

python
rx.flex(
    rx.button(
        "Hello World",
        color_scheme="tomato",
    ),
    rx.button(
        "Hello World",
        color_scheme="teal",
    ),
    spacing="2",
)

Shades

Sometime you may want to use a specific shade of a color from the theme. This is recommended vs using a hex color directly as it will automatically change when the theme changes appearance change from light/dark.

To access a specific shade of color from the theme, you can use the rx.color. When switching to light and dark themes, the color will automatically change. Shades can be accessed by using the color name and the shade number. The shade number ranges from 1 to 12. Additionally, they can have their alpha value set by using the True parameter it defaults to False. A full list of colors can be found here.

python
rx.flex(
    rx.button(
        "Hello World",
        color=rx.color("grass", 1),
        background_color=rx.color("grass", 7),
        border_color=f"1px solid {rx.color('grass', 1)}",
    ),
    spacing="2",
)
python
rx.table.root(
    rx.table.header(
        rx.table.row(
            rx.table.column_header_cell("Name"),
            rx.table.column_header_cell("Type"),
            rx.table.column_header_cell("Description"),
        ),
    ),
    rx.table.body(
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "color",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    "Str",
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "The color to use. Can be any valid accent color or 'accent' to reference the current theme color.",
                style=cell_style,
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "shade",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.link(
                    rx.code(
                        "1 - 12",
                        style={
                            "color": rx.color("gray", 11),
                            "border_radius": "0.25rem",
                            "border": f"1px solid {rx.color('gray', 5)}",
                            "background": rx.color("gray", 3),
                        },
                        class_name="code-style",
                    ),
                    href="https://www.radix-ui.com/colors",
                )
            ),
            rx.table.cell(
                "The shade of the color to use. Defaults to 7.", style=cell_style
            ),
        ),
        rx.table.row(
            rx.table.row_header_cell(
                rx.code(
                    "alpha",
                    style={
                        "color": rx.color("violet", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('violet', 5)}",
                        "background": rx.color("violet", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                rx.code(
                    "Bool",
                    style={
                        "color": rx.color("gray", 11),
                        "border_radius": "0.25rem",
                        "border": f"1px solid {rx.color('gray', 5)}",
                        "background": rx.color("gray", 3),
                    },
                    class_name="code-style",
                )
            ),
            rx.table.cell(
                "Whether to use the alpha value of the color. Defaults to False.",
                style=cell_style,
            ),
        ),
    ),
    variant="surface",
    margin_y="1em",
)

Regular Colors

You can also use standard hex, rgb, and rgba colors.

python
rx.flex(
    rx.button(
        "Hello World",
        color="white",
        background_color="#87CEFA",
        border="1px solid rgb(176,196,222)",
    ),
    spacing="2",
)

Toggle Appearance

To toggle between the light and dark mode manually, you can use the toggle_color_mode with the desired event trigger of your choice.

python
from reflex.style import toggle_color_mode


def index():
    return rx.button(
        "Toggle Color Mode",
        on_click=toggle_color_mode,
    )

Appearance Conditional Rendering

To render a different component depending on whether the app is in light mode or dark mode, you can use the rx.color_mode_cond component. The first component will be rendered if the app is in light mode and the second component will be rendered if the app is in dark mode.

python
rx.color_mode_cond(
    light=rx.image(
        src="https://web.reflex-assets.dev/logos/light/reflex.svg",
        alt="Reflex Logo light",
        height="4em",
    ),
    dark=rx.image(
        src="https://web.reflex-assets.dev/logos/dark/reflex.svg",
        alt="Reflex Logo dark",
        height="4em",
    ),
)

This can also be applied to props.

python
rx.button(
    "Hello World",
    color=rx.color_mode_cond(light="black", dark="white"),
    background_color=rx.color_mode_cond(light="white", dark="black"),
)