5 Ways to Write CSS Styles in React

Cover image

There are many ways to style your React components. 🤓

In this guide, we will cover ways to style React components. We will show you 5 different ways and you decide which one you prefer best! 😁

Style your component your way

These are the component-styling ways we will discuss:

We are going to replace the same styles below using different component-styling ways.

/* BeautifulButton.css */

.button {
  color: #494949;
  text-transform: uppercase;
  text-decoration: none;
  background: #ffffff;
  padding: 20px;
  font-size: 20px;
  border: 4px solid #494949;
  display: inline-block;
  transition: all 0.4s ease 0s;
}

.button:hover {
  color: #ffffff;
  background: #f6b93b;
  border-color: #f6b93b;
  transition: all 0.4s ease 0s;
}

.button--primary {
  color: #ffffff;
  text-transform: uppercase;
  text-decoration: none;
  background: #f6b93b;
  padding: 20px;
  font-size: 20px;
  border: 4px solid #f6b93b;
  display: inline-block;
  transition: all 0.4s ease 0s;
}

.button--primary:hover {
  color: #494949;
  background: #ffffff;
  border-color: #494949;
  transition: all 0.4s ease 0s;
}

Regular CSS

This is the easiest and most straight forward way to add styles to a React component.

import React from 'react';
import './BeautifulButton.css';

const MyBeautifulButton = props => {
  return (
    <div>
      <button className={props.primary ? 'button--primary' : 'button'}>
        Button
      </button>
    </div>
  );
};

export default MyBeautifulButton;

Inline Styling

import React from 'react';

const MyBeautifulButton = props => {
  const button = {
    color: '#494949',
    textTransform: 'uppercase',
    textDecoration: 'none',
    background: '#ffffff',
    padding: '20px',
    fontSize: '20px',
    border: '4px solid #494949',
    display: 'inline-block',
    transition: 'all 0.4s ease 0s'
  };

  const primaryButton = {
    ...button,
    color: '#ffffff',
    background: '#f6b93b',
    borderColor: '#f6b93b'
  };

  return (
    <div>
      <button style={props.primary ? primaryButton : button}>Button</button>
    </div>
  );
};

export default MyBeautifulButton;

Note: The camel-case is necessary for the inline-styling to work! For example, borderColor.

Inline-styling is simple and works out of the box but has many limitations.

For example, there is no straight froward way to add hover effect.

Recommendation: Use the inline-styling paradigm only with small simple components. 😇

CSS Modules

import React from 'react';

import styles from './my-beautiful-button.module.css'; // must have extension .module.css.
// my-beautiful-button.module.css has the same styles as Button.css.

const MyBeautifulButton = props => {
  return (
    <div>
      <button
        className={props.primary ? styles['button--primary'] : styles.button}
      >
        Button
      </button>
    </div>
  );
};

export default MyBeautifulButton;

All styles from a CSS module get scoped within that component that imported it. That means you don't have to worry about global name-conflicts. 😌

Note: You must include the sub-extension .module in the name. Otherwise the styles will load as regular CSS and you may have name-conflicts.

Preprocessors

Using preprocessors such as SCSS, LESS or Stylus is straight forward in React.

You need to add the preprocessor loader and then in the same way as regular CSS you can import the files.

import React from 'react';
import './button.scss'; // <-- Once webpack configs have the right loader this should work like regular scss.

const MyBeautifulButton = props => {
  return (
    <div>
      <button className={props.primary ? 'button--primary' : 'button'}>
        Button
      </button>
    </div>
  );
};

export default MyBeautifulButton;

CSS in JS

CSS in JS is a pattern where you would define all your styles inside the component. Like inline-styling but a lot more powerful.

Let's have a look at how we would write the same button styles using Styled Components and Emotion.

Styled Components

import React from 'react';

import styled from 'styled-components';

const MyBeautifulButton = props => {
  const BeautifulButton = styled.button`
    color: #494949;
    text-transform: uppercase;
    text-decoration: none;
    background: #ffffff;
    padding: 20px;
    font-size: 20px;
    border: 4px solid #494949;
    display: inline-block;
    transition: all 0.4s ease 0s;
    &:hover {
      color: #ffffff;
      background: #f6b93b;
      border-color: #f6b93b;
      transition: all 0.4s ease 0s;
    }
  `;

  const BeautifulPrimaryButton = styled(Button)`
    color: #ffffff;
    background: #f6b93b;
    border-color: #f6b93b;
    &:hover {
      color: #494949;
      background: #ffffff;
      border-color: #494949;
    }
  `;

  return (
    <div>
      {props.primary ? (
        <BeautifulPrimaryButton>Button </BeautifulPrimaryButton>
      ) : (
        <BeautifulButton>Button</BeautifulButton>
      )}
    </div>
  );
};

export default MyBeautifulButton;

Emotion

Emotion has two ways of adding styles, the css API and the styled API.

Here is an example of how using the css API looks like:

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/* @jsx jsx */
import React from 'react';
import { jsx, css } from '@emotion/core';

const BeautifulButton = css`
  color: #494949;
  text-transform: uppercase;
  text-decoration: none;
  background: #ffffff;
  padding: 20px;
  font-size: 20px;
  border: 4px solid #494949;
  display: inline-block;
  transition: all 0.4s ease 0s;
  &:hover {
    color: #ffffff;
    background: #f6b93b;
    border-color: #f6b93b;
    transition: all 0.4s ease 0s;
  }
`;

const BeautifulPrimaryButton = css`
  ${Button};
  color: #ffffff;
  background: #f6b93b;
  border-color: #f6b93b;
  &:hover {
    color: #494949;
    background: #ffffff;
    border-color: #494949;
  }
`;

const MyBeautifulButton = props => {
  return (
    <div>
      <button css={props.primary ? BeautifulPrimaryButton : BeautifulButton}>Button</button>
    </div>
  );
};

export default MyBeautifulButton;

Emotion's styled API is very similar to Styled Components. Here is an example:

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/* @jsx jsx */
import React from 'react';
import { jsx, css } from '@emotion/core';

import styled from '@emotion/styled';

const BeautifulButton = styled.button`
color: #494949;
text-transform: uppercase;
text-decoration: none;
background: #ffffff;
padding: 20px;
font-size: 20px;
border: 4px solid #494949;
display: inline-block;
transition: all 0.4s ease 0s;
&:hover {
  color: #ffffff;
  background: #f6b93b;
  border-color: #f6b93b;
  transition: all 0.4s ease 0s;
}
`

const BeautifulPrimaryButton = styled(BeautifulButton)`
color: #ffffff;
background: #f6b93b;
border-color: #f6b93b;
&:hover {
  color: #494949;
  background: #ffffff;
  border-color: #494949;
}
`

const MyBeautifulButton = (props) => {
  return (
    <div>
      {props.primary ? <BeautifulPrimaryButton>Button </BeautifulPrimaryButton> : <BeautifulButton>Button</BeautifulButton>}
    </div>
  );
};

export default MyBeautifulButton;

Note: You can add a babel plugin to avoid writing the required file's top line.

/** @jsx jsx */

CSS in JS is a powerful pattern. It makes a lot of things easier when building large complex web applications.

There is one main difference between Styled Components and Emotion.

Styled Component offers only the styled API. But, Emotion offers two ways to add the styles: the css and the styled APIs.

Recommendation: For large applications, we would recommend using Emotion. 👌

Here are other CSS in JS libraries worth checking out:

Now you know your options when it comes to styling components! Which one do you prefer? 🤔

Support us

Enjoyed the article? Share the summary thread on twitter.



Author image

Learn how to build scalable, fast and accessible web applications.

Follow us on Twitter

hello@nordschool.com