loading...
Cover image for Let's Take a Look at CSS in JS with React in 2019 - CSS & Inline Styling

Let's Take a Look at CSS in JS with React in 2019 - CSS & Inline Styling

phizzard profile image Phil Tietjen ・5 min read

Let's Take a Look at CSS in JS with React in 2019 - CSS & Inline Styling

CSS in JS isn't unique to React, however, I'm a little React fanboy and it happens to be one of my favorite JS libraries to write front end applications with, so I'm going to be talking about CSS in JS solutions specifically with React and how I feel about them!

Introduction with regular CSS

Before we dive into anything I think we should take a look at what we can accomplish with some good ol' CSS in the context of a React application.

// Button.js
import React from 'react'
import './Button.css'

const Button = () => {
  return(
    <button className="button button-green">
      I think I'm green
    </button>
  )
} 
/* Button.css*/
.button{
  border-style: solid;
  border-width: 2px;
  border-radius: 2rem;
}

.button-green {
  background-color: green;
  border-color: white;
  color: white;
}

So this looks fairly normal, right? It looks like some regular HTML and CSS besides the className. If you're not familiar with React class === className because class is a reserved word in JS, and since JSX is HTML with embedded JS this is a nono.

Issues I have run into using CSS with React

Before we start here I need to state that I am definitely not an expert or guru of CSS. I can kick my feet around with it and make responsive rules that look alright. I can't name any crazy CSS tricks or create an animated Pikachu in pure CSS.

Because of this, I'm not going to even pretend to talk about all the pitfalls with CSS or any new features with CSS that aim to fix these pitfalls, so I'm going to drop this excellent resource from 2014. I'll let you decide if it still holds up! ;)

Global Namespaces ❌

Are you saying I'll be able to use BEM?

Gif: Morpheus smiling

When the time comes, you won't have to.

If you took a look at that link I put up above, you'll notice that global namespaces are the first issue it covers with CSS. However, we've all felt this tremor, which is why naming conventions like BEM exist.

.button and .button-green from our CSS example is already 2 global namespaces we introduced.

As an application grows, I've found that the CSS rules are written also grows continuously. Creating unnecessary duplicate styles with small tweaks and unused styles bulking up the application. While there are configs out there to make sure unused CSS isn't included in your bundle, they don't vanish from your codebase and that sucks.

Loose Coupling ❌

While you can structure your react app so that your component styles exist in the same directory as your component, there's nothing in your component file strictly tying it together. Instead, you're referencing the rules you've specified for your selectors. Despite the file structure, those styles can be referenced elsewhere; It's just another thing to think about.

Clunky Controls ❌

When using just CSS you're more or less stuck controlling all your styling changes based on changing the class of an element. While this seemed maybe more natural with something like Vanilla Javascript or JQuery, it always felt hacky to me when using React. You have this direct access to your view all in separated components yet we're throwing all this logic to reference different combinations of CSS classes.

I know Inline Styling

gif: Morpheous leans close and says "Show me"

Another way to style your React app without any modules is inline styling. Now, pay no attention to the person in the back yelling about how bad inline styling can be, because that's actually me in disguise. We were all taught that inline styles in HTML are bad and class-based styles were rad. However, this is JSX.

// Button.js
import React from 'react'

const Button = () => {
  const buttonGreen = {
    backgroundColor: "green",
    border: "2px solid white",
    borderRadius: "2rem"
    color: "white"
  };

  return(
    <button style={buttonGreen}>
      I think I'm green
    </button>
  )
}

This doesn't look so bad right?

You may notice that the CSS rules here don't quite look the same. Instead of seeing Kebab Case we are using Camel Case for our rules. They are mapped out in a Javascript Object with their values wrapped in quotations as a string.

Global Namespaces ✅

Neo and Morpheus in a dojo, ready to fight

In our inline styling example, buttonGreen is local to that file, so we can have as many buttonGreen vars as we want across the application without running into any conflicts or following any specific naming conventions!

Loose Coupling ✅

Gif: Morpheus tells neo to "Free your mind" and leaps across a rooftop

With these styles being locally defined, you can't use these styles unless you go through the effort to exporting and importing them; Ideally, there are enough steps to stop the bad things from happening.
I think it also promotes developers to use React in a more intended way to create generic components that can be reused.

Clunky Controls ✅

// Button.js
import React from 'react'

const Button = ({backgroundColour, colour, children}) => {
  const buttonStyles = {
    backgroundColor: backgroundColour,
    color: colour,
    border: "2px solid white",
    borderRadius: "2rem"
  };

  return(
    <button style={buttonStyles}>
      {children}
    </button>
  )
}

// SomePage.js
import React from 'react';
import Button from 'Button';

const SomePage = () => (
  <Button backgroundColour="blue" colour="white">I'm going to be blue</Button>
)

Now, this is a super simple example but we can see that we have given our Button specific control over the colours through some props that's passed into the component. I like this approach because it's self-documenting and it keeps all the logic in the component; I know exactly what the prop in the component is controlling and the usage of the component is very clear that it's setting the backgroundColour to blue and the colour to white.

What I don't like about Inline Styling

Neo getting kicked by Morpheus

Using objects for styles

I'm not a fan of this syntax for styling. It's enough of a departure that can cause enough tedious work converting CSS into Javascript objects replacing ; with ,, wrapping rules in "", and casing the keys into camel case. It's also scary enough for your designers that this approach can get shut down at the sight of it.

Inline styling is still inline

At the end of the day, this is still inline styling and your HTML will still end up with those ugly style attributes.

Would I personally use Inline Styling in React?

Nope.

But that's not the end for dear old CSS in JS! There are some pretty cool packages out there that do cool stuff and try to solve all kinds of issues regarding readability, scalability, and performance with CSS in JS.

In this series, I'm going to try and look at a diverse pool of these solutions whether they are highly rated or buried underneath.

As of writing this, I have used Styled Components, Emotion, and JSS. If you think one is really cool feel free to drop a comment about it!

I'm also on Twitter if you want to follow me or chat on there. I sometimes post things there!

Posted on by:

phizzard profile

Phil Tietjen

@phizzard

I'm a Senior Developer and Co-host of Friday Night Deploys Podcast. I'm also a dad that likes to play video games and lift, always failing to keep it real with the kidz.

Discussion

markdown guide
 

I'm interested to see the rest of the series 😉

I actually really like inline styles for some things... it's nice to not have to switch files and pollute the global space with styles just for one little thing... but it can also become a bad habit.

And I actually really didn't like most css-in-js that I ran across, but after being forced to use it for awhile, it wasn't so bad either; so I'm interested to hear your other posts!

 

Glad you're liking the series so far!

I initially bounced off the second I first saw and gradually got invested until it's all I do for styling in react in my personal projects.

There's still a few I've seen that I think messy up a component but I won't spoil my series entries here ;).

I'm pretty excited to go over ones I know, revisit ones I bounced off, and find new ones!

 

I'm listening. *clicks follow* :D
By the way, personally what I'm doing now is that I have scss files that I import around, and I only use inline styles where I want to do parameter expansion from JS into the styles. Like when there is a color picker for a field in the CMS. Or when I want to do some responsive dynamics.

 

Super appreciate the follow :D. Now I have obligations to continue the series!

I've used SCSS with react too though I was soured because those stylesheets were poorly written. I enjoyed the nesting rules though!

Glad to hear it's working for you though!

 

You can put your style object outside the render function. Or as static property of the function/class. otherwise you are gonna to recreate the same style each time

 

Thanks for commenting, You're totally right Pasquale! Ideally you can store your style variables really anywhere you want to and import them into your components.

However I did want to just show off a simple example that can also show props affecting styles.

We can also use useMemo to avoid recreating the same style on every render but I figured it was just a little out of scope for what I wanted to show :)