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