🎨 cascading stylesheets

or, the "and you thought JS was bad" part.

ie6, or, “how i think kids have it too easy these days”. (source unknown :-/)ie6, or, “how i think kids have it too easy these days”. (source unknown :-/)

tl;dr


CSS for newbies

if you’re absolutely new to CSS, start here at the Mozilla Developer Network (or MDN). they’re the people that make Firefox and have the best reference guides for CSS. in general though this guide assumes you’ve got a base understanding of CSS so go forth and mess around with the language as much as you can before moving on to the rest of the more complicated stuff.

playgrounds

an easy way to get started is by checking out some of these tools that let you play around with the language:

  • CodeSandbox: lets you mess around with a React app in real-time.
  • CodePen: a social development environment for front-end designers and developers.
  • CSS Zen Garden: shows you how a single HTML page can look a 1,000 different ways. this site goes way back and was inspiration to many a designer/developer. (you can mess around with the CSS via the Developer Tools in your browser.)

defining colors, a minor note

there’s been a lot of standards around color, beginning with rgb and including other fancier things like hsl. the new “king” of color definition is oklch.


beyond CSS: CSS Modules and CSS-in-JS

this guide is about writing an application not a regular webpage. to that end, you shouldn’t be using regular CSS with <style> tags anymore — as your application grows and more contributors add to it, you will drown in a sea of madness and salty tears. yes, your mother taught you to wash behind your ears, brush your teeth, and never, EVER use inline styles in your HTML. but those days are over and a new era has come.

the truth is that this space is still rapidly in development and the dust isn’t quite settled yet. i think there are compelling arguments for both CSS-in-JS and CSS Modules. you’ll probably fine going with either these days.

finally, there's also truth in this: whatever you pick may never be enough

CSS Modules: a happy middle ground

CSS Modules are a great way to get a lot of the benefits of CSS-in-JS without leaving the CSS world altogether. here’s a helpful primer on getting started.

CSS-in-JS: some compelling arguments

CSS-in-JS forgoes CSS files altogether and says we should have our styling where our components are. think about it this way. when you’re sharing HTML these days, we tend to do so via HTML-in-JS. in other words, one can create React components and publish them to the general web to share to fellow developers. similarly, one could argue, the best way to share CSS is to package them inside of something standard like JS.

great reads on the topic

  • Farewell CSS: a great take on why you should probably be doing CSS-in-JS.
  • CSS in JS: a watershed moment of a slideshow arguing for you to forget everything you now about how inline styles are bad.
  • A Unified Styling Language: from the co-creator of CSS modules, an argument for CSS-in-JS and to leave behind things like BEM which are only conventions/opt-in vs. something that’s baked-in to a methodology.

package options
again, there’s so much action going on in this space that it’s still to be decided what paradigm will win here. for now though, my tentative recommendation is emotion.

  • emotion: rapidly in development, new to the party. “next-gen”.
  • Pigment CSS: MUI's companion CSS kit that may(?) end up being a thing one day?
  • glamorous: uses objects in JS to declare CSS for a particular module.
  • Aphrodite: uses objects and lets you do server-side rendering, too.
  • polished: lets you write CSS rules in a more semantic way. the “lodash” of CSS-in-JS.
  • Linaria: zero-runtime CSS in JS.
  • styletron: has some smart optimizations around CSS generation.
  • JSS: one of the original packages — uses a dynamic stylesheet to add rules. (you’ll need react-jss as well.)
  • Radium: one of the original packages in this space.
  • Atomic CSS: bleh. unreadable.
  • styled-components: is dead ☠️.
  • to help you decide: an article going over (some of) the various libraries.

anti-Tailwind

this is an opinionated guide, remember? everything in my soul tells me to keep Tailwind away with a 10-foot pole. it's vendor lock-in embodied in a library, it has its own bespoke version of CSS that you have to learn, it becomes a garbled, cluttered mess within your HTML/JSX, ugh, ugh, ugh!

yes, it's very conveniently "spoken" by LLMs but trying to maintain it is untenable. Tailwind just ends up being a bloody mess once the codebase has any amount of real complexity or the number of collaborators grows. we webdevs went through this experience with CoffeeScript before. yes, it was elegant, neat, enticing — and, in the end, we needed to rewrite it all to stay relevant.

relevant reading:

there are so. many. libraries. coming out that are built on Tailwind, and, yeah, they look a peach. but ugh, mark my words, in 10 years, this madness will (hopefully) be behind us, leaving us to cleanup the strangling kudzu-like vines of unmaintainable code for decades to come.


create-next-app

related to the previous section on JS, i’ll mention again here the technologies included by default related to CSS for you to use out of the box.

  • PostCSS: enables lots of nice CSS capabilities, including the following:
    • postcss-preset-env: lets you use new/experimental (stage 3+) CSS features today. this depends on your browserslist field in package.json. (historical note: postcss-preset-env was previously known as “cssnext”)
    • autoprefixing: adds compatibility support for different browsers.
    • CSS Modules: let’s you import CSS into your JS. name your css files *.module.css to take advantage.
  • Sass: provides support for a superset of CSS. (note: disabled by default. needs to be turned on by installing the node-sass package.)

CSS Reset

sanitize.css is a CSS Reset that helps normalize things across browsers, a lesser problem these days but still important. Chris Coyier's "reset": an opinionated take on a reset.

conventions

CSS Modules
when you can, it’s suggested to use CSS Modules which provide great scoping for your CSS to a particular JS module. first, name your CSS file [name].module.css and then you can use it in your JS module as such (take note of the composes keyword and what it’s doing):

// Button.module.css
.className {
color: green;
background: red;
}
.otherClassName {
composes: className;
color: yellow;
}
// 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.otherClassName}>Button</button>;
}
}

preprocessors

given the recommendation for CSS Modules/CSS-in-JS i might steer you away from CSS preprocessors (which would add yet another layer top of an already complex stack of technologies). but, if that’s your thing, then take a look at Sass.

the advantages Sass can give you are things like:

  • variables
  • nesting of rules
  • mixins
  • operators
  • and more!

(historical note: other packages in the space are things like Less but the community isn’t as strong there and the support from other vendors isn’t as robust.)


looking ahead

there’s a bunch of CSS features constantly in the making. i had this section listing things from 2018 that were exciting and the neat thing is that the CSS development flywheel has only continued to produce great stuff!


resources