PostCSS from Sass

by mmyoji

2 min read

Motivation

I'd used Sass (.scss) in a Nuxt.js project. But Nuxt.js doesn't support Sass natively. Removing node-sass and sass-loader will make me easier to maintain the project.

In addition, I have lately heard that PostCSS is modern CSS pre-/post-processor and you should use it. Nuxt.js also supports it w/o installing additional npm packages.

Then I switched from Sass to PostCSS.

What is changed?

A quantity of Sass in the project was not so large and it was not hard to migrate into PostCSS. There might be another difficulties for a larger Sass project, I would write what was required in the migration.

Variables

$primary-blue: #58c3e0;

.button {
  background-color: $primary-blue;
}

to

:root {
  --primary-blue: #58c3e0;
}

.button {
  background-color: var(--primary-blue);
}

Single Line CSS

I'm not sure this might be happen always. At least a single line CSS didn't work in my project. (and unfortunately, there was no warning/error logs for it.)

/* doesn't work */
.foo {
  color: red;
}

/* works */
.foo {
  color: red;
}

Nesting

There're plugins for CSS nesting: postcss-nested and postcss-nesting.

If you use postcss-preset-env (and I personally think you should use this normally) with stage: 3, you can use the latter postcss-nesting. see: https://github.com/csstools/postcss-preset-env#features

But if you want to use Sass-style nesting, use postcss-nested and you don't need to rewrite nested CSSs.

postcss-nesting (and future CSS nesting) will be like this:

.foo {
  color: red;

  /* need `&` unlike Sass nesting */
  & .hoge {
    font-size: 12px;
  }
}

/* becomes */

.foo {
  color: red;
}

.foo .hoge {
  font-size: 12px;
}

@for

There's postcss-for plugin. However, because the utility CSS classes in my project were not often used, I removed @for and wrote some classes manually.

darken color function

There's very useful color functions in Sass: darken and lighten. Luckily we have a plugin postcss-color-function, but it requires a slight change for the former Sass functions.

.foo {
  background-color: darken($primary-blue, 20%);
}

to

.foo {
  background-color: color(var(--primary-blue), shade(20%));
}

This seems verbose and I gave up using this plugin. I prepare darker/lighter variables and use them directly.

Summary

There might be harder if your project has a lot of Sass features, but it's better choise to use PostCSS for future CSS development and it worths it.

You can add necessary plugins gradually when you need it in PostCSS development. Though we often write styles inside a component (like React and Vue.js) in modern web development, global styling sometimes might be necessary and PostCSS is one of the best choices for it.

References