CSS in JS patterns
Tags: cssinjs, css, react, javascript
Published: 2020-02-10 18:27:30

---
title: CSS in JS patterns
published: true
date: 2020-02-09 16:49:03 UTC
tags: css-in-js,css,react,javascript
canonical_url: https://krzysztofzuraw.com/blog/2020/css-in-js-patterns
---

I have read a lot of articles about CSS in JS. Yet the majority of them are just some introductory articles or why having CSS in JS is a nice thing. So I decided to write my own blog post with CSS-in-JS patterns that I either heard, used or am currently using while working with CSS in JavaScript.

This blog post is for those who know basic of CSS-in-JS: `styled` component or what is CSS `prop`. I’ll be using only one library here - [emotion](https://github.com/emotion-js/emotion).

# Styled Component

The first pattern is the most basic - you take your `div`, `a` and other HTML tags and wrap them using `styled` function. If you have the following structure:

```html
<div>
  <h1>Header</h1>
  <p>Description</p>
</div>
```

Then you create corresponding components wrapped in styled:

```tsx
<Card>
  <Header>Header</Header>
  <Description>Description</Description>
</Card>

const Card = styled('div');
const Header = styled('h1');
const Description = styled('p');
```

At my job in [Ingrid](https://www.ingrid.com/) we have a whole application written using `styled` components and in the beginning, it seems like a really nice pattern, yet if you don’t rethink how you want to reuse your components you will end up having a lot of duplications.

This is our problem right now as we need to maintain a whole file next to the component that has all CSS-in-JS definitions. It is easy to read but if you need to change some padding or color you need to dive deep into `style.tsx` file and search for your particular component.

# Styled Component with CSS classes

Here you have `styled` function - but it is used only on the top-level component. The rest is using either `classNames` or CSS selectors. Going back to the previous example:

```html
<div>
  <h1>Header</h1>
  <p>Description</p>
</div>
```

You will end up with:

```jsx
<Card>
  <h1 className="header">Header</h1>
  <p>Description</p>
</Card>

const Card = styled('div', () => ({
  '.header': {
    // styles applied to header class
  },
  '& > p': {
    // styles applied to p tag via CSS selector
  },
}));
```

This is our current solution for having CSS-in-JS. It is not perfect - as sometimes we need to have a header of different colors based on some prop. Then we add a new prop into `Card`, and pass it down for calculation:

```jsx
const Card = styled('div', props => ({
  '.header': {
    color: props.useWhite ? 'white' : 'red',
  },
}));
```

Which not only has a problem with mental cognition about why `Card` should have `useWhite` prop and why the heck it is needed here? Also, you need to use [shouldForwardProp](https://emotion.sh/docs/styled#customizing-prop-forwarding) as React will start shouting at you for passing down the `useWhite` custom prop to HTML element.

The benefit of this pattern is that you have one `styled` component that holds the truth about your CSS.

# CSS Prop

The last pattern is taking advantage of having `css` prop available on any HTML tag. If we look at the example:

```html
<div>
  <h1>Header</h1>
  <p>Description</p>
</div>
```

Using `css` prop we will have:

```jsx
<div
  css={
    color: componentProps.useWhite ? 'white' : 'red',
  }
>
  <h1 css={theme => ({ color: theme.black })}>Header</h1>
  <p css={descStyles}>Description</p>
</div>
```

The benefit of it is that there is no need to add `shouldForwardProp` - you can take all data directly from the context of the component. As you can see in the above example the first argument to `css` is a `theme` object that can contain emotion-theming values.

If you are using TypeScript you will need to type `theme` via `css={(theme: Theme) => ({})}` insteadof having typed `styled` if you are using this guide.

I haven’t used this pattern in production code but I see some drawbacks from the beginning - what if you start using `css` prop too much? Then you will end up with long HTML tags that have both logic of rendering and styling. One solution for that problem is to extract styles to its own variable is done with `p` tag in the example above.

# Conclusion

You can check all of those examples in more complicated scenarios below in codesandbox:


{% codesandbox css-in-js-patterns-zz7ns %}


In this blog post I wanted to present 3 CSS-in-JS patterns:

- styled prop. This is the easiest one to use but has a problem with having a lot of boilerplate to write and maintain the code.
- styled classes. This is somewhat in the middle between styled & css prop. You create the main wrapper with `styled` and then inside its definition use CSS selectors to style tags inside. It has smaller boilerplate but the question is still here - how should you structure your code?
- css prop. This is the pattern I haven’t used yet. It seems like a nice way of writing CSS-in-JS but I have to try it first.