Skip to content
Theme UI
GitHub

Theming

Theming with Theme UI is based on a Theme Specification including a theme.styles object for styling MDX elements and other components. By adhering to a standard Theme Specification, Theme UI is designed to be interoperable with as many other libraries as possible.

Colors

Add a theme.colors object to provide colors for a theme. In order to ensure color palettes are as interoperable as possible, the following color keys should be used for defining a base set of colors:

KeyDescription
textBody foreground color
backgroundBody background color
primaryPrimary brand color for links, buttons, etc.
secondaryA secondary brand color for alternative styling
accentA contrast color for emphasizing UI
highlightA background color for highlighting text
mutedA faint color for backgrounds, borders, and accents that do not require high contrast with the background color

Beyond these base colors, any additional values can be added to a theme to augment the base color palette.

Color modes

Multiple color modes, i.e. dark mode, can be handled with a nested modes object that matches the shape of the default colors.

// example colors with dark mode
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
modes: {
dark: {
text: '#fff',
background: '#000',
primary: '#0cf',
}
}
}

Learn more in the color mode docs.

Typography

Core typographic values can be stored in the following theme keys:

  • fonts (font families)
  • fontSizes
  • fontWeights
  • lineHeights
  • letterSpacings
// example theme object
{
colors,
fonts: {
body: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
heading: 'Georgia, serif',
monospace: 'Menlo, monospace',
},
fontSizes: [
12, 14, 16, 20, 24, 32, 48, 64
],
fontWeights: {
body: 400,
heading: 700,
bold: 700,
},
lineHeights: {
body: 1.5,
heading: 1.125,
},
letterSpacings: {
body: 'normal',
caps: '0.2em',
},
}

Value scales

The following theme keys are used to define scales for values that can be used in other parts of a theme:

  • space (margin, padding, gap, etc)
  • sizes (width, height, etc)
  • borders (border)
  • borderWidths (border-width)
  • borderStyles (border-style)
  • radii (border-radius)
  • shadows (box-shadow)
  • zIndices (z-index)

For example, after setting space like this in your theme:

space: [0, 4, 8, 16, 32, 64, 128, 256, 512],

You can reference the array values in your theme styles, by index:

<Box
sx={{
padding: 2 // Equals 8px
}}
/>

The values can also be named using an object, like this:

sizes: {
wide: 2048,
container: 1024,
narrow: 512,
},

Then used by name, such as sx={{ maxWidth: 'narrow' /* 512px */ }}.

Styles

Styles for elements rendered in MDX can be added to the theme.styles object. This is the primary API for applying typographic styles in Markdown content. Styles within this object have access to other values in the theme object, such as colors, fonts, and space.

// example theme styles
{
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
},
fonts: {
body: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
heading: 'Georgia, serif',
},
fontWeights: {
body: 400,
heading: 700,
},
styles: {
h1: {
fontSize: 32,
fontFamily: 'heading',
fontWeight: 'heading',
color: 'primary',
mt: 4,
mb: 2,
},
}
}

Root styles

To add base, top-level styles to the <html> element, use theme.styles.root.

// example with root styles
{
fonts: {
body: 'system-ui, sans-serif',
heading: 'Georgia, serif',
},
fontWeights: {
body: 400,
heading: 700,
},
styles: {
root: {
// uses the theme values provided above
fontFamily: 'body',
fontWeight: 'body',
},
},
}

Breakpoints

To configure the default breakpoints used in responsive array values, add a breakpoints array to your theme. Each breakpoint should be a string with a CSS length unit included or a string including a CSS media query. String values with a CSS length unit will be used to generate a mobile-first (i.e. min-width) media query. The breakpoints can then be used to apply responsive styles.

// example custom breakpoints
{
breakpoints: [
'40em', '@media (min-width: 56em) and (orientation: landscape)', '64em',
],
}

Configuration flags

The theme object can also include configuration options for Theme UI, which are nested in the config object. The following keys can be used to enable and disable certain features.

FlagDefaultDescription
useCustomPropertiestrueEnables CSS custom properties to help mitigate a flash of unstyled content during rehydration
useRootStylestrueAdds styles defined in theme.styles.root to the <html> element along with color and background-color
initialColorModeName'default'The key used for the top-level color palette in theme.colors
useColorSchemeMediaQuerytrueInitializes the color mode based on the prefers-color-scheme media query
useBorderBoxtrueAdds a global box-sizing: border-box style
useLocalStoragetruePersists the color mode in localStorage

Default theme

If your custom theme doesn’t override these properties, Theme UI will use these default values.

{
breakpoints: [40, 52, 64].map((n) => n + 'em'),
space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 72],
}

Example theme

The following example is from the Base Preset.

// example base theme from @theme-ui/presets
export const theme = {
breakpoints: ['40em', '52em', '64em'],
space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
fonts: {
body:
'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
heading: 'inherit',
monospace: 'Menlo, monospace',
},
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 96],
fontWeights: {
body: 400,
heading: 700,
bold: 700,
},
lineHeights: {
body: 1.5,
heading: 1.125,
},
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
secondary: '#30c',
muted: '#f6f6f6',
},
text: {
heading: {
fontFamily: 'heading',
lineHeight: 'heading',
fontWeight: 'heading',
},
},
styles: {
root: {
fontFamily: 'body',
lineHeight: 'body',
fontWeight: 'body',
},
h1: {
variant: 'text.heading',
fontSize: 5,
},
h2: {
variant: 'text.heading',
fontSize: 4,
},
h3: {
variant: 'text.heading',
fontSize: 3,
},
h4: {
variant: 'text.heading',
fontSize: 2,
},
h5: {
variant: 'text.heading',
fontSize: 1,
},
h6: {
variant: 'text.heading',
fontSize: 0,
},
pre: {
fontFamily: 'monospace',
overflowX: 'auto',
code: {
color: 'inherit',
},
},
code: {
fontFamily: 'monospace',
fontSize: 'inherit',
},
table: {
width: '100%',
borderCollapse: 'separate',
borderSpacing: 0,
},
th: {
textAlign: 'left',
borderBottomStyle: 'solid',
},
td: {
textAlign: 'left',
borderBottomStyle: 'solid',
},
},
}

For alternative pre-made themes, check out the presets package, and to see open source custom themes, check out this collection. For more information on the Theme UI theme object, see the Theme Specification docs.

Edit the page on GitHub
Previous:
Getting Started with Gatsby
Next:
The sx Prop