PostCSS (or, migrating away from Sass)
What is it? A lot of folks hear of it, and think they should adopt it instead of scss. It’s not really comparable, though.
I’ve finally stopped using Sass
in my projects. I still love it, it got me far. However, I’m increasingly finding I don’t need it. Instead, I’m all-in on PostCSS.
PostCSS is, in brief, a way to import and scope your CSS. That’s pretty much it. Its usefulness stems from the ability to generate a list of css names from a css file, which it then makes available to your JS. So, whatever you’re doing in JS-land can directly reference (or, “communicate with”, if you like) the CSS bridge that PostCSS provides.
A few details
Why is this useful? Well, if you use any kind of JS framework, it might be nice to be able to reference particular CSS styles or classes in your JS code. During build time, the compiler can see what’s referenced in a component and dynamically pull in and generate the necessary CSS for it.
// special.module.css
.burger { background: red; }
.bonkers { background: pink; }
// special.js
import styles from 'special.module.css';
<main className={styles.cat}> // JSX
<main :class="styles.bonkers"> // Vue, etc
Here, we have .burger
and .bonkers
in our CSS. Behind the scenes, PostCSS generates a JSON file with these class names mapped to their respective value(s), which can be imported in our JS.
More powerfully, those names are local to each JSON file from which they were scoped; they can later be obfuscated – rewritten with a hash – as part of the build pipeline. This enables the dev to maintain a verbose list of class names without worrying if they’ll clash with other global styles: PostCSS guarantees that the obfuscated (“hashed”) CSS class names it generates will be unique and have uniform specificity (unless you write nested CSS). Additionally, there’s no need to resort to other naming conventions such as BEM, and you won’t be burdened with trying to find a super-awesome and totally-perfect class name. It doesn’t matter.
Transition pains
It’s plain CSS, and you’re probably used to some of the niceities that Sass wrought. I often encounter instances that make me wish I had a particular feature from Sass – for example, importing vars into a file, using the Sass-style of nested syntax, or using the ancestor reference &
. Early on, I kept forgetting that I was now authoring plain CSS and didn’t have these things. Oh, and note that PostCSS does not have variables, either.
Now, that might all seem dire, and you may opt to use PostCSS in tandem with Sass if you wish. But, you may not need to. You might find that CSS vars
work better than alllll the vars you had previously in Sass. And, there are a multitude of packages to provide a “Sass-like” experience in your PostCSS landscape. For example:
- use Sass-style imports with
postcss-import
- enjoy Sass-style nested syntax with
postcss-nested
(Bonus – this includes thenested-ancestors
package!)
The end?
Sass revolutionized how I thought about CSS, and composed and structured it. But, I probably won’t be going back, which is bittersweet.