Skip to content
Theme UI
GitHub

Color Modes

Color modes can be used to create a user-configurable dark mode or any number of other color modes.

Defining colors

In the theme.colors object, add a nested modes object that will contain keys for optional color modes. The name for the base color mode is default.

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

The colors defined at the root of the colors object will be accessible as default. All colors found in colors.modes will be referenced by their key. The above example will have two modes:

  • default
  • dark

Setting the color mode

Use the useColorMode hook in your application to change the color mode. This value will be stored in localStorage and used whenever the page is loaded.

import React from 'react'
import { useColorMode } from 'theme-ui'
export default props => {
const [colorMode, setColorMode] = useColorMode()
return (
<header>
<button
onClick={e => {
setColorMode(colorMode === 'default' ? 'dark' : 'default')
}}>
Toggle {colorMode === 'default' ? 'Dark' : 'Light'}
</button>
</header>
)
}

Applying colors

The previous steps will enable a color mode state and pass it through context. To apply the color mode values to the <body> element, render the ColorMode component in your application.

If you're using Gatsby to build your app, follow the instructions below.

import React from 'react'
import { ThemeProvider, ColorMode } from 'theme-ui'
import theme from './theme'
export default props => (
<ThemeProvider theme={theme}>
<ColorMode />
{props.children}
</ThemeProvider>
)

Gatsby plugin

For use in a Gatsby site, install and use gatsby-plugin-theme-ui to add the ThemeProvider to the root of your application. The plugin will help prevent the flash of colors that can happen during page load when a user has a non-default color mode set.

npm i gatsby-plugin-theme-ui

This plugin will look for a src/gatsby-plugin-theme-ui/index.js file to import and pass to the ThemeProvider.

// gatsby-config.js
module.exports = {
plugins: ['gatsby-plugin-theme-ui'],
}

See the Gatsby plugin docs for more info.

Advanced

There are a few advanced usages of color modes when you need more flexibility. For most usecases, you won't need to reference this section.

Turn off custom properties

The default implementation of Theme UI color modes uses CSS custom properties. If you're supporting browsers that don't support custom properties you can turn off this setting. This will cause the colors to flash on initial page load.

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

Renaming the default color mode

The colors you define at the root level, outside of theme.colors.modes is named default. If you'd like to customize it you can do so by setting initialColorModeName:

{
initialColorModeName: 'light',
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
modes: {
dark: {
text: '#fff',
background: '#000',
primary: '#0cf',
}
}
}
}

Initialize dark mode with prefers-color-scheme: dark

To initialize a dark color mode based on the prefers-color-scheme: dark media query, add the useColorSchemeMediaQuery flag to your theme. This will set the initial color mode to dark when @media (prefers-color-scheme: dark) matches. If you do not have a color mode named dark, this will have no effect.

{
useColorSchemeMediaQuery: true,
colors: {
text: '#000',
background: '#fff',
modes: {
dark: {
text: '#fff',
background: '#000',
}
}
}
}
Edit the page on GitHub
Previous:
Styling MDX
Next:
Styled