Skip to content
Theme UI
GitHub

Theme Specification

Theme UI is based on a theme specification, which can be used in other libraries and applications for increased interoperability. This specification is also intended to help ensure that themes created for Theme UI are suitable for white-label applications and general purpose theming.

The theme object is made up of the following data types:

  • Scales: plain objects or arrays of values for related CSS properties
  • Variants: partial style objects that can be used for stylistic component variants or making part of an application themeable
  • Styles: a collection of styles for MDX content

Theme Scales

The theme object is made up of the following scales (i.e. property-specific objects) for use in CSS styles.

Theme KeyCSS Properties
bordersborder, border-top, border-right, border-bottom, border-left, border-block, border-block-end, border-block-start, border-inline, border-inline-end, border-inline-start
borderStylesborder-style, border-top-style, border-bottom-style, border-left-style, border-right-style, border-block-end-style, border-block-start-style, border-block-style, border-inline-end-style, border-inline-start-style, border-inline-style
borderWidthsborder-width, border-top-width, border-bottom-width, border-left-width, border-right-width, border-block-end-width, border-block-start-width, border-block-width, border-inline-end-width, border-inline-start-width, border-inline-width, column-rule-width
colorscolor, background, accent-color, background-color, border-color, caret-color, column-rule-color, outline-color, text-decoration-color, border-top-color, border-bottom-color, border-left-color, border-right-color, border-block-color, border-block-end-color, border-block-start-color, border-inline-color, border-inline-end-color, border-inline-start-color, fill, stroke
fontsfont-family
fontSizesfont-size
fontWeightsfont-weight
letterSpacingsletter-spacing
lineHeightsline-height
opacitiesopacity
radiiborder-radius, border-top-right-radius, border-top-left-radius, border-bottom-right-radius, border-bottom-left-radius, border-end-end-radius, border-end-start-radius, border-start-end-radius, border-start-start-radius
shadowsbox-shadow, text-shadow
sizeswidth, min-width, max-width, height, min-height, max-height, flex-basis, block-size, inline-size, max-block-size, max-inline-size, min-block-size, min-inline-size, column-width
spacemargin, margin-top, margin-right, margin-bottom, margin-left, margin-block, margin-block-end, margin-block-start, margin-inline, margin-inline-end, margin-inline-start, padding, padding-top, padding-right, padding-bottom, padding-left, padding-block, padding-block-end, padding-block-start, padding-inline, padding-inline-end, padding-inline-start, scroll-margin, scroll-margin-top, scroll-margin-right, scroll-margin-bottom, scroll-margin-left, scroll-padding, scroll-padding-top, scroll-padding-right, scroll-padding-bottom, scroll-padding-left, inset, inset-block, inset-block-end, inset-block-start, inset-inline, inset-inline-end, inset-inline-start, top, right, bottom, left, grid-gap, grid-column-gap, grid-row-gap, gap, column-gap, row-gap
transitionstransition
zIndicesz-index
// example theme
{
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
secondary: '#05a',
accent: '#609',
muted: '#f6f6f6',
},
fonts: {
body: 'system-ui, sans-serif',
heading: 'system-ui, sans-serif',
monospace: 'Menlo, monospace',
},
fontWeights: {
body: 400,
heading: 700,
bold: 700,
},
lineHeights: {
body: 1.5,
heading: 1.125,
},
}

Color

The theme.colors scale (i.e. color palette) should be an object literal with the following keys.

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

Other color keys can be added, including raw color values for aliasing the values above.

Color Modes

To use Theme UI color modes, color scales should include at least a text and background color. These values are used to set body foreground and background colors. Color modes should be defined as nested objects within a theme.colors.modes object. Each key in this object should correspond to a color mode name, where the name can be anything, but typically light and dark are used for applications with a dark mode.

// example color scale with modes
{
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
secondary: '#05a',
muted: '#f6f6f6',
modes: {
dark: {
text: '#fff',
background: '#000',
primary: '#0cf',
secondary: '#09c',
muted: '#111',
},
papaya: {
// this color mode will fallback to the root color object
// for values not defined here
text: '#433',
background: 'papayawhip',
},
},
},
}

Typography

To ensure that themes built for Theme UI are as portable and interoperable as possible, the following keys should be defined within each theme scale. Additional keys can be included for more complex styling.

  • fonts
    • body: default body font family
    • heading: default heading font family
    • monospace: default monospace font family for <pre>, <code>, etc.
  • fontWeights
    • body: body font weight
    • heading: default heading font weight
    • bold: default bold font weight
  • lineHeights
    • body: body line height
    • heading: default heading line height

Font Sizes (Typographic Scale)

Font sizes are typically defined as an array, from smallest to largest.

// example fontSizes scale
{
fontSizes: [
12, 14, 16, 20, 24, 32, 48, 64,
],
}

Number values will be converted to pixel units. For other units, use string values, e.g. '1em'.

For illustration purposes, the index values of the array can be thought of as loosely mapping to heading levels, but these values are not in any way tied to HTML elements.

IndexHeading-Level Equivalent
0h6
1h5
2h4
3h3
4h2
5h1

Variants

Use variants to define custom groups of styles. These are commonly used for typographic styles, buttons, and themeable layout components. Variants are also used to style built-in components.

// example typographic style variants
{
colors: {
white: '#FFFFFF',
primary: '#663399',
text: '#393939',
secondary: '#DAA520',
},
fonts: {
body: 'system-ui, sans-serif',
heading: 'system-ui, sans-serif',
monospace: 'Menlo, monospace',
},
fontWeights: {
body: 400,
heading: 700,
bold: 700,
},
lineHeights: {
body: 1.5,
heading: 1.125,
},
// variants can use custom, user-defined names
text: {
heading: {
fontFamily: 'heading',
lineHeight: 'heading',
fontWeight: 'heading',
},
caps: {
textTransform: 'uppercase',
letterSpacing: '0.1em',
},
},
// variants for buttons
buttons: {
primary: {
// you can reference other values defined in the theme
color: 'white',
bg: 'primary',
},
secondary: {
color: 'text',
bg: 'secondary',
},
}
}

User-defined variants can then be referenced in the sx prop or in theme.styles.

// example using variants
<h1
sx={{
variant: 'text.heading',
}}>
Hello
</h1>
<button
sx={{
variant: 'buttons.primary',
}}>
Beep
</button>

Variants support the same style objects as the sx prop, which means responsive array values, functional values, and extending other variants are supported.

Styles

The Theme UI styles object is primarily used as a way to style MDX content and helps avoid the need to use global CSS. The styles defined within this object can also be used with the Themed component.

The theme.styles object may include the following keys, which map to elements that can be rendered by markdown:

  • p (paragraph)
  • a (anchor link)
  • h1 (heading)
  • h2
  • h3
  • h4
  • h5
  • h6
  • img
  • pre
  • code
  • ol (ordered list)
  • ul (unordered list)
  • li (list item)
  • blockquote
  • hr (horizontal rule)
  • em (emphasis)
  • table
  • tr (table row)
  • th (table header)
  • td (table data)
  • strong
  • del
  • b (bold)
  • i (italic)
  • inlineCode (MDX-specific key for <code> that is not a child of <pre>
  • thematicBreak (MDX-specific key for <hr>)
  • div (not rendered in MDX)
  • root (theme-ui-specific)

Objects within theme.styles can reference other values in the theme object. For example, headings can be defined with values from the typographic scales.

// example heading styles
{
styles: {
h1: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
fontSize: 5,
},
},
}

Variants can also be used within the theme.styles object.

// example heading using text styles variant
{
// ...base theme object
text: {
heading: {
fontFamily: 'heading',
fontWeight: 'heading',
lineHeight: 'heading',
}
},
styles: {
h1: {
variant: 'text.heading',
fontSize: 5,
}
}
}

Aliasing Colors and Other Scales

In many design systems, developers choose to create an additional layer of abstraction for mapping individual components to specific scale values. With Theme UI, variants are the mechanism to use for such abstractions.

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',
],
}
Edit the page on GitHub
Previous:
API
Next:
Demo