DEV Community

loading...
Cover image for Create a theme with styled-components easily in 3 steps. πŸ’…

Create a theme with styled-components easily in 3 steps. πŸ’…

vaibhavkhulbe profile image Vaibhav Khulbe ・5 min read

What if you're working on a React based project and suddenly your design team says:

"Yo, we need to completely change the entire theme of the app due to blah and blah reasons..."

Maybe you're not convinced with their reasons or maybe you just need to do this for fun. Whatever the reason, it's quite annoying if you’re just using plain old CSS (even with variables) to apply the global or per-element styles.

What comes to the rescue is some method by which you can easily change the entire color, font, gradient, etc. values in one go, a place where all of these are defined in a central place so you don’t have to change things here and there.

What I'm talking about is creating your own theme with styled-components.


A quick note on styled-components πŸ“

styled-components is a library that allows you to write actual CSS code to style your components inside a JS file. This follows the CSS-in-JS concept which allows developers to style using tagged template literals giving extensive flexibility and more control.

All in all, a great merger of CSS and JS! Here are some of its features:

  • Automatic critical CSS: it keeps track of which components are rendered and injects their styles and nothing else, automatically.

  • No class name bugs: there are no duplication, overlap, or misspellings.

  • Easier deletion of CSS: if the component is unused and gets deleted, all its styles get deleted with it.

  • Simple dynamic styling: styling of a component based on its props without having to manually manage dozens of classes.

What we will be styling? πŸ’…

This:

styled components button theming

We will be theming out two buttons using styled-components. Notice that we have:

  • Different default and hover colors.
  • Different font styles.

Not this:

Hair styling GIF

Create global styles! 😍

After you're done installing the library, head over to your index.js file. Here, all the theme data will go such as the colors, fonts, etc.

STEP 1️⃣ : Create a theme object

This will house all the theme objects we need. Currently, we are only changing the colors and fonts.

const theme = {
  colors: {
    primary: "#6200ee",
    primaryVariant: "#ede6ff",
    secondary: "#008073",
    secondaryVariant: "#deffff"
  },
  fonts: {
    material: "Roboto",
    default: "Montserrat"
  }
};
Enter fullscreen mode Exit fullscreen mode

As we can see, there are four color options, one for each variant; primary and secondary. As for the font, we also need to include them in our index.html file via the <link> method as follows:

<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />

<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;700&display=swap" rel="stylesheet" />
Enter fullscreen mode Exit fullscreen mode

STEP 2️⃣ : Use the ThemeProvider component

Next, import the ThemeProvider helper component from styled-components. This is used to inject the theme into all styled-components in the component tree, via the Context API.

We need to wrap our top-level component i.e. <App /> with this. But for it to actually recognize the theme object we wrote above, we need it to pass it on as:

<ThemeProvider theme={theme}>
    <React.StrictMode>
        <App />
    </React.StrictMode>
  </ThemeProvider>
Enter fullscreen mode Exit fullscreen mode

Hence, now the render methods becomes:

ReactDOM.render(
  <ThemeProvider theme={theme}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </ThemeProvider>,
  rootElement
);
Enter fullscreen mode Exit fullscreen mode

STEP 3️⃣ : Create the buttons and add the theme!

Before we hop into the buttons, did you see that the body color of the demo is not white but instead off-white? Well, here, the global style of the app was triggered.

Using the createGlobalStyle helper function, we can change or reset the base styles of the entire application.

For this to happen, we need to add the <Global /> component just before the <App /> starts inside the App() function.

Now we can add global styles by defining the usual styled-component:

const Global = createGlobalStyle`
  body {
    width: 50%;
    padding: 10px;
    background: #fffaeb;
  }
`;
Enter fullscreen mode Exit fullscreen mode

Okay, let's move to those two buttons. We can create two components; <PrimaryButton /> and <DefaultButton />

The usual styles (without colors and fonts) for the buttons are as follows:

  .
  .
  .
  width: 50%;
  height: 50px;
  cursor: pointer;
  transition: all 200ms ease;
  text-decoration: none;
  outline: none;
  border: none;
  border-radius: 10px;
  float: left;
  .
  .
  .
Enter fullscreen mode Exit fullscreen mode

To get the value from the theme which is passed via the ThemeProvider component, we will use our good old friend in React, i.e. props!

Start with the template literal syntax to pass on the props parameter to our arrow function, this can now get the global theme object via props.theme. Now we got the theme object, so we can assign the values as follows:

background: ${(props) => props.theme.colors.primary};
color: ${(props) => props.theme.colors.primaryVariant}; 
Enter fullscreen mode Exit fullscreen mode

We applied the colors, now what about the hover effect? styled-components makes it really easy to add pseudo-classes whether it's :hover or :active. Just invert the values of the background and color inside the :hover object:

:hover {
    background: ${(props) => props.theme.colors.primaryVariant};
    color: ${(props) => props.theme.colors.primary};
  }
Enter fullscreen mode Exit fullscreen mode

The same method is applied to other objects inside our theme such as for the different fonts:

  .
  .
  .
  font-family: '${(props) => props.theme.fonts.material}';
  font-weight: 500;
  .
  .
Enter fullscreen mode Exit fullscreen mode

And that's pretty much it! You have used a theme in styled-components. Of course, this is just the beginning, you can bring in the entire library of design assets and tokens with your theme to make it even more dynamic.


More resources 🀩

Go ahead with theming when you read from these resources:


Thanks for reading, I appreciate it! Have a good day. (βœΏβ—•β€Ώβ—•βœΏ)



πŸ“« Subscribe to my weekly developer newsletter πŸ“«

PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, here's my Medium profile.

Discussion

pic
Editor guide
Collapse
terrythreatt profile image
Terry Threatt

Very helpful!

Collapse
vaibhavkhulbe profile image
Vaibhav Khulbe Author

Thanks for reading! :)