How does CSS fit into React?

Written by linasmnew | Published 2018/02/14
Tech Story Tags: javascript | programming | web-development | react | coding

TLDRvia the TL;DR App

There are a lot of different ways in which you can write CSS for your React applications, I would go as far as to say that you actually have more options for styling React applications than traditional web applications.

Let’s define some of these options:

  • Standard CSS
  • Inline Styles
  • CSS Modules
  • CSS-in-JS

Now let’s take a closer look at each one of these.

Standard CSS

This is the traditional and the most common way of writing CSS. You create a style.css file, add all of your styles inside of it, then import the stylesheet and reference the styles within your JSX via className or id attributes.

Note that you don’t have to limit your styles within a single stylesheet, you can just as well split them into multiple files and place them next to the components which they are supposed to target.

Also note that you can keep on using your everyday CSS libraries and frameworks such as SASS, LESS, Bootstrap, Semantic UI, etc., as well, React doesn’t limit you in any way.

Inline Styles

Inline styles refer to writing CSS directly inside of HTML markup via the style attribute. In React, using JSX, this looks like this:

<p style={{color: "red"}}>Hello World</p>

Inline styles are probably the most limited approach in terms of styling full blown applications since they cannot make use of all of the CSS features such as pseudo selectors, animations and media queries.

In practise they are mostly used for basic style modifications such as color toggling based on a condition, but I have also heard of people and even companies using this as their sole styling mechanism.

(Be aware that, arguably, inline styles can also be considered as part of CSS-in-JS, because technically you do write them inside of JS files with React. The reason I chose to put them into their own category was because CSS-in-JS libraries are typically more complex than just writing styles inside of a style attribute — they instead introduce some sort of a higher level abstraction as you will see in the CSS-in-JS section.)

CSS Modules

With CSS modules you create a CSS file for every type of component that you want to style the same way that you might do with the “Standard CSS” option, however the difference here is that with CSS modules the styles are scoped locally which means that unlike “Standard CSS” they don’t leak into other components.

The styles being locally scoped also means that you can forget about implementing your own local scoping strategies or following methodologies such as BEM which require you to manually create and type out long class or id names.

How to use within React:

Use css-loader inside of your webpack.config with modules property set to true, or download a complete library such as css-modules, once setup use as follows:

  • create a CSS file for whatever components you want to style
  • write your CSS
  • import this CSS file inside of the target components
  • reference these styles within your components via their className and id attributes

How are CSS Modules implemented behind the scenes?

CSS Modules work by taking your CSS files and running them through a CSS Module compiler which does two things:

  • modifies the class and/or id names inside of your CSS files to make them unique
  • produces a JS file containing the mapping between the newly generated names and the old names

Hence why you can use named imports with CSS modules — you are not actually importing your CSS, but rather the JS that was produced by the CSS Module compiler.

CSS-in-JS

As the name suggests with CSS-in-JS you write your CSS inside of JavaScript files rather than CSS files, how you write and apply them, however, is very dependant on the specific CSS-in-JS library that you use.

Behind the scenes CSS-in-JS is usually implemented in one of the following three ways (or a combination of):

  • via inline styles
  • via a <style> element
  • via a <link> element at build time by extracting styles into a CSS file

For the sake of not making the article overly long, we will only look at a single CSS-in-JS implementation, that is styled-components, which also happens to be one of the most popular implementations out there.

Before we break down how it works however, let’s first look at an example:

import React, { Component } from "react";
import styled from "styled-components";

const Wrapper = styled.div`
  max-width: 600px;
  margin: 0 auto;
`;

class HelloWorld extends Component {
  render() {
    return (
      <Wrapper>
        <p>Hello World</p>
      </Wrapper>
    );
  }
}

Let’s now break this example down. At the top we declare a variable called Wrapper and ask styled-components to create and give us back a div component consisting of the styles that we have defined within the backticks — in this case we are asking it for a div component with the following stylesmax-width: 600px; margin: 0 auto;.

We then add this Wrapper component inside of our render method and use it like a regular div.

In simple terms all that is going on here is you tell styled-components what kind of a built-in component you want and how it should be styled and styled-components give you that component back.

How do the styles get applied behind the scenes?

Styled-components rely on the<style> element, so internally you can think of it like creating and appending<style> your styles </style> to the documents head section. Also since it provides local style scoping, it takes care of generating and applying unique class names.

To better visualise this, let’s run the above code snippet and see what it produces after being added to the DOM:

...
<head>
  ...
  <style>
    /* sc-component-id: sc-bdVaJa */
    .sc-bdVaJa {}
    .brPdfu {
      max-width: 600px;
      margin: 0 auto;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="sc-bdVaJa brPdfu">
      <p>Hello World</p>
    </div>
  </div>
</body>
...

As you can see it does look like what we expected it to look like. The only surprise is the extra empty style declaration .sc-bdVaJa {}which based on the comment right above it/* sc-component-id: sc-bdVaJa */seems to suggest that styled-components keep track of which component the styles belong to — presumably for some sort of internal performance optimisation or something along those lines.

If you like what you see, you might also want to checkout another, very similar, CSS-in-JS library called Emotion, it is very similar to styled-components but gives you the option of extracting all of your styles into a CSS file, at build time, which then get linked into the document via the <link> element. Why is this useful? Because the generated stylesheet can be cached by the browser.

For a full list of the most popular CSS-in-JS solutions see this github repository.

Finish line

Congratulations for getting to the end :), thanks for reading and hope you learned something of use. Twitter: linasmnew.


Published by HackerNoon on 2018/02/14