React in Style

Managing CSS in React Applications

About Me

  • Software Engineer at Arundo Analytics
  • Love-hate relationship with CSS
  • Designer-turned-developer who loves declarative UI

Why We Love Components in Web

  • Encapsulated, neatly packaged bits of something
  • Easy to compose and reuse
  • Easy to develop; narrow focus

Why We Love React

  • UI as a function of state
  • Unopinionated
  • Massive and rich ecosystem
  • ... and lots more!

Motivation

  • React does not impose a particular styling pattern
  • CSS is fundamentally antithetical to componentization
  • Observation of how the others do it, i.e. Vue single file components

Motivation

Styling solution fatigue...

  • CSS
  • Sass
  • Less
  • CSS-Modules
  • styled-components
  • Emotion
  • JSS
  • Linaria?
  • Aphrodite??
  • Classy???
  • Inline styles?!?!?!?

Let's talk about a few

  • CSS and Sass/SCSS
  • CSS-Modules
  • styled-components, or "CSS-in-JS"*

*bit of a misnomer

CSS/Sass

"Raw/vanilla" CSS is FREE and available everywhere, no buy-in, no strings.

 

Sass/SCSS is preprocessed CSS with superpowers.

// CSS

nav {
  background: red;
}

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

nav li {
  display: inline-block;
}


// SCSS

nav {
  background: red;

  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }
}

Sass w/ React

Common patterns:

 

Separate styles directory - styles live together, components live elsewhere

 

 

Sass w/ React

Common patterns:

 

"Sidecar style" - Component is accompanied by Sass file, styles usually scoped to component using a root class name

The "Good"

  • Export a stylesheet, reuse anywhere
  • Tried and true; mature patterns (7-1 pattern, BEM convention, etc.)
  • Nesting, shared constants, mixins, oh my

The "Bad"

  • If not manually scoped, CSS pollutes global scope
  • Overriding stylesheets can be rough (*cough* semantic-ui-css)
  • Clear separation between styles and rest of component (cue arguments)

Sass/SCSS 

Runtime variables can be achieved using native Custom CSS Properties

Creates unique class names scoped locally by default, exposes a JS map

 

Can go hand-in-hand with Sass/Less and custom CSS properties as best-of-both-worlds "CSS-in-JS" option

// Button.module.css

.error {
  background-color: red;
}


// another-stylesheet.css

.error {
  color: red;
}


// Button.js

import React, { Component } from 'react';
import styles from './Button.module.css'; // Import css modules stylesheet as styles
import './another-stylesheet.css'; // Import regular stylesheet

class Button extends Component {
  render() {
    // reference as a js object
    return (
        <button className={styles.error}>
            Error Button
        </button>
    );
  }
}

The "Good"

  • CSS stylesheet export with semi-intelligible class names
  • Scoped by default, like Web Components without the shadow DOM
  • Composition
  • Pass around references to class names in JS

The "Bad"

  • Overriding styles in custom React components still hard
  • Still dealing with imperative classNames-based logic 

CSS-Modules

// ...
return (
    // ...
    <Button 
        className={
            props.active 
            ? styles.active 
            : styles.default
        } 
    />
    // ...
)

Exposes React component factories using tagged template literal syntax

 

Styles get dynamically injected into <head>

 

Wrap React components with `styled` to add styling

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0.5em 1em;
  padding: 0.25em 1em;

  ${props => props.primary && css`
    background: palevioletred;
    color: white;
  `}
`;

const Container = styled.div`
  text-align: center;
`

render(
  <Container>
    <Button>Normal Button</Button>
    <Button primary>Primary Button</Button>
  </Container>
);

The "Good"

  • Easy to use, easier to dynamically and declaratively style
  • Override styles easily
  • Dynamic properties without using CSS Custom Properties

The "Bad"

  • Firmly coupled w/ React
  • No stylesheet export
  • Lots of foot-guns
  • This:

styled-components

Demo time!

$ git clone https://github.com/mvasigh/react-styled-example.git
$ cd react-styled-example
$ npm install
$ npm start

React in Style

By Mehdi Vasigh

React in Style

3-21-2019 Presentation on styling solutions for React applications

  • 259