Easy theming with CSS in JS

You read about CSS in JS and you wonder: what can this give me that I don’t already have with CSS modules?

Your code is maintainable, scope is local, all is good.

But what if you need theming support? And you want your users to be able to change the theme at runtime?

With CSS in JS, this is supported out of the box.

Let's test 3 of the most used libraries and see how they handle theming!

What was the test?

A day / night theme switcher based on Google Creative Lab's Night and Day project.

What were the libraries?

Click the links to see the step by step process of building the Day/Night switcher with each of them.

What are the conclusions?

All libraries use a similar approach to apply themes

There are two ways to pass a theme:

  • Manually, using the theme prop
<Sky theme={dayTheme}/>
  • Using a ThemeProvider
<ThemeProvider theme={dayTheme}>
    <Sky/>
</ThemeProvider>

To pass the theme to all components in your application you would wrap them in a <ThemeProvider>;

const App = () => (
  <ThemeProvider theme={theme}>
    <SomeComponent>
      <SomeOtherComponent />
    </SomeComponent>
  </ThemeProvider>)

Initial setup is easy

Setup is pretty easy and boils down to just installing the npm packages.

The only steps a bit more involved are with emotion if you decide to use the babel preset. This is recommended as the final bundle size will be much smaller.

Components adapt based on a theme prop

In all examples, components would adapt their styles based on the theme prop made available by the ThemeProvider.

// template literals - styled components
const Sky = styled.div`
  height: 100%;
  width: 100%;
  background-color: ${props => props.theme.skyColor}
`;
// object literals - glamorous
const Sky = glamorous.div({
  height: '100%',
  width: '100%'
}, ({ theme }) => ({
  backgroundColor: theme.skyColor
}));
// emotion works with both

Wrapping up

What's your experience with theming in the React world?

Let me know in the comments below!