Theme
Change the theme for any subtree
Change the theme for any subtree by passing its name to the Theme component.
Usage
Change the theme for any subtree:
Theme updates
Use <ThemeUpdate> to override theme values for a subtree, much like redefining
a CSS custom property on one node. Listed keys override and everything else
inherits from the parent theme.
Values use the same flat grammar as style props. <ThemeUpdate> applies its values
to a whole subtree, so it supports modifiers that describe a subtree:
- Theme:
dark:,light:, or any configured theme name.blue:applies underdark_blue,light_blue, or a theme namedblue. - Platform:
ios:,android:,web:, andnative:.
Interaction states such as hover: and press:, and media queries such as
sm:, describe an element rather than a subtree. They warn in development and
are dropped here.
A named theme and an update compose through nesting:
Keys must be theme keys or custom variables declared in
the config. Unknown keys warn in development and are dropped so web and native
behave the same. <ThemeUpdate> accepts children and typed theme or custom
variable keys. Theme controls such as name and shallow stay on
<Theme>.
Custom variables
Declare design-system values in createTamagui to make them work anywhere a
theme key works: style props, useTheme(), and <ThemeUpdate> values.
Use and redefine them like any other theme value:
References and units
Inline values can reference theme keys and tokens:
backgroundfinds the theme key or custom variable visible at the<ThemeUpdate>node.size.4andcolor.blue-500reference tokens by category.- A bare token name such as
blue-500checks theme keys first, then scans color, space, size, radius, and zIndex tokens. Use the qualified form when a name exists in more than one category.
References resolve at the <ThemeUpdate> node and descendants inherit the result.
Chains are supported, while a reference cycle drops the involved keys on both
platforms with a development warning.
Numbers become px on web and stay numbers on native, matching numeric style
props. Keys ending in opacity, scale, zIndex, weight, flex, grow,
shrink, or ratio stay unitless. Use a string such as "10px"
or px(10) for an explicit pixel value.
Nesting and updates
ThemeUpdate layers stack, with the nearest definition winning per key. A <Theme>
that resolves a new name resets keys defined by that theme. Put the ThemeUpdate
inside that boundary when it should survive the switch. Custom variables are
defined on base themes, so sub-themes inherit their updates.
Changing update values leaves unrelated descendants alone. Tamagui tracks
which keys each component reads, and only readers of a changed key update. On
web, styled components restyle through CSS custom properties without a
JavaScript render. JavaScript readers such as useTheme() and animation
drivers see the same values on both platforms. With settings.fastSchemeChange
on iOS, keys whose light and dark values are literals retain the
DynamicColorIOS fast path.
Defining themes
Themes sit above tokens. Tokens are static values, while themes change per subtree like CSS variables.
Define themes however you want, but the tamagui components style themselves
from a set of pre-defined keys:
background,background-hover,background-press,background-focusborder-color,border-color-hover,border-color-press,border-color-focusshadow-color
These are optional, as you can always set unstyled on any Tamagui component to
use your own styles.
A simplified theme definition:
Passing tokens to themes will reduce CSS, but is not required.
Access theme values through styled() or directly on a component:
Because we defined sub-themes light_pink and dark_pink, the Theme
component will now let us do this:
Notice we just use the name pink.
For larger typed theme suites, see Creating themes,
which introduces createThemes, recipe trees, scales, and relative levels.