Functional styled-components Theme Helpers
One of the most popular CSS-in-JS solutions out there is styled-components, and one of its killer features is the ability to easily create themes for your React applications. There are many ways to work with themes, and in this article I’ll share my method that revolves around creating reusable helper functions to simplify the process and reduce the amount of code involved in styling. We’ll also touch on using the polished library to add some pizzazz and further functionality to a styled-components
theme.
My motivation for this pattern was to achieve the same ease that Sass and Stylus offer for writing functional CSS; I believe that the combination of styled-components
and polished
comes really close.
Project repo available at https://github.com/garethpbk/styled-components-theming.git
Project & Theme Setup
Set up a new create-react-app
project and add the dependencies (or add to an existing project) - go ahead and delete everything except App.js
and index.js
in /src:
styled-components
themes work with the Context API via a <ThemeProvider />
component. In index.js
, import the component and theme and wrap <App />
:
<ThemeProvider />
takes one prop, an object called theme
; create the theme.js
file that was imported and set up the values:
Let’s use our theme colors and sizes in <App />
in a styled component:
Hm. The syntax is kind of…bulky — we have the use the name of the property of the property of the theme object of the props each time. How can we simplify this?
Creating Helper Functions
Functions to the rescue! Let’s create some reusable helpers functions to make it easier to access theme values. In theme.js
:
Now we can import and use this function anytime we need a color in a styled component:
Let’s do the same for sizes:
Alright, maybe it’s not that much less code right now, but this pattern really shines when you’re dealing with complex themes and nested theme objects. It puts the power of JavaScript functions in your hands for managing theme styling.
Pizzazz with Polished
Lastly let’s use some polished
features via helper functions in theme.js
:
In <App />
let's use this on a new styled component:
If you’ve used Sass’s lighten feature, this should feel familiar.
Why can’t we just import lighten
directly into the component? Try it - ${lighten(getColor('secondary'), '0.2')}
- it isn't parsed correctly. Keeping it in the theme means it's only imported from polished
once, and doesn't rely on having direct access to getColor
in the component.
One more — let’s utilize the rgba
feature from polished for easily controllable text shadows:
rgba
automatically converts hex values to rgb values (exactly like the Sass function of the same name). This is great because it means we don't have to re-declare color values in different formats; the availability of default parameters is also a nice tool for setting base values. Add to <Content />
:
That wraps up my method of theming styled-components
; functions make for a powerful, infinitely expandable system. In the example project you'll also find a simple grid component created with breakpoint values in the theme.