Styling Components in React

Published | 4 min read

As I mentioned in my previous posts there are quite a few ways to create components in React.js. As it happens there are also quite a few ways to style components as well.

The great thing about React is you can create components in isolation. However, if you are not careful you could end up with conflicting CSS styles.

CSS has come a long way especially with the ability to use Sass and Less to create computed styles but you still need to be careful to make sure you aren’t affecting something else in your application. For anyone who has had to use !important you know what I am talking about.

So let’s have a look at the different ways to style components.

Adding standard classes

There are a few cases where you are going to need to use standard css classes. As we saw in my previous post, class is a protected keyword in JSX. To deal with this we have to use className instead.

function PrimaryButton({ children }) {
  return <button className="button is-primary">{children}</button>
}

The attribute className works in exactly the same was as class does in normal HTML and you can use it to reference styles from an external style sheet.

This is particularly useful if you are converting an existing project to use React or you are referencing class names from an external package. You can import stylesheets directly into your components with import ./Button.css.

Inline CSS

Another way of styling React components is with inline CSS. This is probably my least favourite way of styling components in react but it does solve the issue of having conflicting styles as the styles are scoped to the component.

The style that you provide to the component is written as a javascript object and uses camel case instead of the normal css casing. e.g. border-colour becomes borderColor.

const buttonStyle = {
  backgroundColor: '#00d1b2',
  borderColor: 'transparent',
  color: '#fff',
  cursor: 'pointer',
  justifyContent: 'center',
  paddingBottom: '.5em',
  paddingLeft: '1em',
  paddingRight: '1em',
  paddingTop: '.5em',
  textAlign: 'center',
  whiteSpace: 'nowrap',
}

function PrimaryButton({ children }) {
  return <button style={buttonStyle}>{children}</button>
}

It is easy to get caught out if you forget to camel case when of your styles with this method.

CSS Modules

Another way to scope styles to the component is to use CSS modules. With CSS modules you can write your styles in a standard style sheet.

button.css

.button {
  cursor: pointer;
  justify-content: center;
  padding-bottom: 0.5em;
  padding-left: 1em;
  padding-right: 1em;
  padding-top: 0.5em;
  text-align: center;
  white-space: nowrap;
}

.primary {
  background-color: #00d1b2;
  border-color: transparent;
  color: #fff;
}

button.jsx

import styles from './button.css'

function PrimaryButton({ children }) {
  return (
    <button className={[styles.button, styles.primary].join(' ')}>
      {children}
    </button>
  )
}

When you are using multiple classes that are imported in this way you can’t just reference them in the string as they are variables. One option is to use the join method shown in the example above.

Another option is to use template literals:

import styles from './button.css'

function PrimaryButton({children}) {
  return <button className=`${styles.button} ${styles.primary}`>{children}</button>
}

You can also use the classnames package which is a bit more natural to write.

import styles from './button.css'
import classnames from 'classnames'

function PrimaryButton({ children }) {
  return (
    <button className={classnames(styles.button, styles.primary)}>
      {children}
    </button>
  )
}

One of the great things with classnames is you can also do conditional classes. This is particularly useful if you want to programmatically have styles apply.

import styles from './button.css'
import classnames from 'classnames';

function PrimaryButton({children}) {
  return <button className={classnames(styles.button,{styles.primary : true})}>{children}</button>
}

Styled Components

The last method I am going to share today is using the styled-components library. Styled components allow you to add css styles that are locally scoped without the need to create separate css files.

import styled from 'styled-components'

const Button = styled.button`
  cursor: pointer;
  justify-content: center;
  padding-bottom: 0.5em;
  padding-left: 1em;
  padding-right: 1em;
  padding-top: 0.5em;
  text-align: center;
  white-space: nowrap;

  background-color: ${props => props.primary && '#00d1b2'};
  border-color: ${props => props.primary && 'transparent'};
  color: ${props => props.primary && '#fff'};
`

<Button primary>Click Me</Button>

You can also create styled components from other components.

import styled from 'styled-components'

const Button = styled.button`
  cursor: pointer;
  justify-content: center;
  padding-bottom: 0.5em;
  padding-left: 1em;
  padding-right: 1em;
  padding-top: 0.5em;
  text-align: center;
  white-space: nowrap;
`

const PrimaryButton = styled(Button)`
  background-color: #00d1b2;
  border-color: transparent
  color: #fff
`

<PrimaryButton>Click Me</PrimaryButton>

Final thoughts

There are many ways to style components in React. Which one you use will depend on the project you are working on. If you are using an external stylesheet from a library such as Bootstrap or Bulma then simple CSS classes is probably best.

Of course if you have additional styling you want to use on top you could always use styled-components as well.

ALSO ON ALEXHYETT.COM

Stack vs Heap Memory - What are the differences?

Stack vs Heap Memory - What are the differences?

  • 30 November 2022
In modern programming languages such as C# or Java, we tend to take memory management for granted. Gone are the days when we need to call malloc to request enough memory for our variables. Luckily a lot of that is done for us by the runtimes so we do...
Code Katas: Can They Make You A Better Developer?

Code Katas: Can They Make You A Better Developer?

  • 21 November 2022
They say “practice makes perfect”, although I much prefer “practice makes improvement”. Either way, how do you practice being a programmer? If you are already working as a software developer then you will be getting some practice from working on larg...
Git Flow vs GitHub Flow

Git Flow vs GitHub Flow

  • 10 November 2022
Losing code that you have spent hours writing can be painful, which is why we use version control (or source control) to store our code and manage changes. Version control is even more important if you are working in a team, without it code, changes ...
I Posted on YouTube Consistently for 1 Month. This is What Happened!

I Posted on YouTube Consistently for 1 Month. This is What Happened!

  • 02 November 2022
As part of my creative sabbatical, I have been posting a new software development video on my YouTube channel every Monday and Friday. It takes a long time to grow on YouTube, and I knew this going in but I have been pleasantly surprised with my grow...
Bitwise Operators and WHY we use them

Bitwise Operators and WHY we use them

  • 26 October 2022
Bitwise operators are one of those concepts that a lot of programmers don’t understand. These are not used a great deal anymore so you can get away with not knowing them but they can still come in handy for a number of different scenarios. If you end...
8 Data Structures you NEED to Know

8 Data Structures you NEED to Know

  • 26 October 2022
You can get pretty far in programming without understanding Data Structures, but eventually, you are going to need to know them, understand how they work and when to use them. https://www.youtube.com/watch?v=SCkbQSPH--A What is a data structure? A da...
Binary Numbers Explained for Programmers

Binary Numbers Explained for Programmers

  • 21 October 2022
Everyone knows that computers run on ones and zeros. This is because CPUs are made up of billions of transistors, which are basically just on-off switches. Any code you write needs to be processed by a computer and therefore has to be converted to b...
Beginners Guide to Programming

Beginners Guide to Programming

  • 12 October 2022
A lot of my articles are aimed at intermediate to advanced developers, but as part of my creative sabbatical, I am working on creating content for those just starting out. So in this post I will be covering some of the many questions that beginner pr...