A Guide to Styling your React App
Tags: react, webdev
Published: 2020-08-18 08:59:41

---
title: A Guide to Styling your React App
published: true
date: "2020-08-18T08:42:05.610Z"
tags: ['react','webdev']
canonical_url: https://maxrozen.com/guide-to-styling-react-app/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/gwfk3bxvn4tvdsq8wai7.jpg
---

If you’re new to React, you might be wondering why there are so many different tutorials that teach different ways to style your React app. The truth is, we’re all still figuring out the best way to do things.

Styles in React were more-or-less worked out in this order:

1. Global CSS
2. CSS Modules
3. CSS in JS ([styled-components](https://styled-components.com/), [Emotion](http://emotion.sh/), etc)
  - Utility-first CSS
  - Styled System
4. Statically extracted CSS in JS

These days, I recommend starting with CSS in JS. If you’d like to know why, read on.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#quick-note)Quick note

When I say styling, I mean writing your CSS styles more-or-less from scratch. If you’re looking for pre-built components, I wrote a [guide to commonly used React component libraries](https://maxrozen.com/guide-to-component-ui-libraries-react/).

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#global-css)Global CSS

Global CSS is likely the way you’re used to styling webpages. You have a giant `styles.css` file, and try to write [BEM](http://getbem.com/naming/) or [SMACSS](http://smacss.com/) names for all of your classes. Alternatively, you have a ton of tiny files, and don’t always know where each class lives.

We as frontend developers quickly realised that global CSS doesn’t really scale. The more teams you have editing a single file, the more likely you are to have CSS that doesn’t do anything (people become too afraid to delete anything in case it breaks).

If you still want to use Global CSS in your React app, all you need to do is import the CSS file at the top level of your React app (assuming you’ve configured webpack to do so, or are using create-react-app).

```jsx
//App.js
import './styles.css';
import React from 'react';

const App = () => {
  return <div className="some-class">some other stuff in here</div>;
};
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#css-modules)CSS Modules

[CSS Modules](https://github.com/css-modules/css-modules) _look_ a lot like Global CSS, in the sense that you’re importing a CSS file into your React component, but under the hood it’s quite different.

A lot of the problems we used to have with Global CSS are gone with CSS Modules.

Your CSS looks like this:

```css
/* style.css */
.makeItGreen {
  color: green;
}
```

and your React Component looks like this:

```jsx
import React from 'react';
import styles from './style.css';

const MyComponent = () => {
  return <div className={styles.makeItGreen}>Green!</div>;
};
```

The key difference here is that only files that import `style.css` will be able to access the class names that it defines, and the class names that get generated during the build process will be unique.

No more conflicts, no more “too afraid to delete things in case it breaks”, just locally scoped CSS. You can also set-up SCSS/LESS support, if you need it.

The really cool thing about this is that you can start to play around with JavaScript to change a component’s styles.

```jsx
import React from 'react';
import styles from './style.css';

const MyComponent = (props) => {
  const myStyle = props.color === 'RED' ? styles.makeItRed : styles.makeItGreen;
  return <div className={myStyle}>{props.color}!</div>;
};
```

Although, that starts to get a bit messy if you’re using several props to change the style and behaviour of your components. What if your styles could just be components?

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#css-in-js)CSS in JS

That’s where CSS in JS comes in.

Libraries like [styled-components](https://styled-components.com/) and [Emotion](https://emotion.sh/docs/introduction) make it possible to wrap components (including divs, spans, `<p>` tags, `<a>` tags) with styles, and use them as React components.

The best part is, you can use all of the standard CSS features you’re used to, such as media queries, and `:hover` and `:focus` selectors.

Our example from above now becomes:

```jsx
import React from 'react';
import styled from '@emotion/styled';
// OR import styled from 'styled-components'

const StyledGreenThing = styled.div`
  color: ${(props) => (props.color === 'RED' ? 'red' : 'green')};
`;

const MyComponent = (props) => {
  return (
    <StyledGreenThing color={props.color}>{props.color}!</StyledGreenThing>
  );
};
```

As of 2020, Emotion and styled-components are evenly matched performance-wise. Contributors to styled-components worked hard to bring their performance up to Emotion’s level, so deciding which one to use isn’t as much of a big deal any more.

Emotion _does_ provide some extra options for styling, such as the [css prop](https://emotion.sh/docs/css-prop), while styled-components tries to keep a single, standard way of doing things via the `styled` API.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#utility-first-css)Utility-first CSS

A guide to styling React apps wouldn’t be complete without mentioning utility-first CSS frameworks such as [Tailwind](https://tailwindcss.com/). You don’t actually need React to use utility-first CSS, but in my opinion, it makes for a better developer experience when you add React and CSS in JS.

In short, Tailwind lets you style your components one class at a time. Here’s what it looks like:

```jsx
<div className="md:flex bg-white rounded-lg p-6">
  <img
    className="h-16 w-16 md:h-24 md:w-24 rounded-full mx-auto md:mx-0 md:mr-6"
    src="avatar.jpg"
  />
  <div className="text-center md:text-left">
    <h2 className="text-lg">Erin Lindford</h2>
    <div className="text-purple-500">Product Engineer</div>
    <div className="text-gray-600">erinlindford@example.com</div>
    <div className="text-gray-600">(555) 765-4321</div>
  </div>
</div>
```

Which creates a component that looks like this:[![Tailwind CSS Example Component](https://maxrozen.com/static/0e68f5fb70d237a6e162757e1bcb84db/2fd48/tailwind-css-example.png "Tailwind CSS Example Component")](https://maxrozen.com/static/0e68f5fb70d237a6e162757e1bcb84db/2fd48/tailwind-css-example.png)

You might be thinking that it’s not a particularly re-usable solution, however it’s possible to use Tailwind class names with your favourite CSS in JS library using [twin](https://github.com/ben-rogerson/twin.macro).

You can then have styled Tailwind components:

```jsx
import tw, { styled } from 'twin.macro';

const Input = styled.input`
  color: purple;
  ${tw`border rounded`}
`;

export const MyStyledInput = () => {
  return <Input />;
};
```


## Styled System

[Styled System](https://styled-system.com/) takes the `styled` API supplied by styled-components or Emotion, and adds utilities as props, rather than class names.

The Styled System approach is particularly powerful when it comes to theming/white labelling, as changing the entire appearance of your app can be done by replacing the `theme.js` file you provide.

Your components end up looking like this:

```jsx
import styled from '@emotion/styled';
import { typography, space, color } from 'styled-system';

const Box = styled('div')(typography, space, color);

const UsedBox = () => {
  return (
    <Box
      fontSize={4}
      fontWeight="bold"
      p={3}
      mb={[4, 5]}
      color="white"
      bg="primary"
    >
      Hello
    </Box>
  );
};
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#statically-extracted-css-in-js)Statically extracted CSS in JS

The trouble with CSS in JS is that it takes JavaScript to load your CSS. This slows things down big time, so people started looking for ways to extract the CSS from CSS-in-JS during build time.

There are a few libraries that can do this:

- [Compiled](https://compiledcssinjs.com/)
- [linaria](https://github.com/callstack/linaria)
- [treat](https://github.com/seek-oss/treat)

Compiled and linaria let you use the `styled` API that you know and love, while giving you the performance benefit of not having CSS in your bundle.

(This is an article from MaxRozen.com. You can read the original by [clicking here](https://maxrozen.com/guide-to-styling-react-app/).)