strazi.org is the design of kevin kennedy

Post CSS

I’ve been using SASS for several years now, and I love it. I’m not an advanced user, but some of the niceties it provides have made writing plain CSS feel quite ancient.

One of my favorite features is nesting. I’ve learned to avoid nesting too deeply, but I like being able to encapsulate a block of styles, and not having to repeat selectors.

My second favorite feature is being able to nest custom media queries. This has proven to be invaluable for responsive design, and further helps to visually group related rules within a single block.

.style {
  width: 50%;
  @include bp(sm) {
    width: auto;
  }
}

Other features I actively use are mixins, extend, variables, and import. There is a lot more to SASS than what I use, but I just never found myself needing to explore all of the additional features. So what finally drove me to change? Syntax highlighting.

My primary editor is Sublime Text, and the principle options for syntax highlighting and tab-completion there are the SASS bundle or the SCSS bundle. Both haven’t been updated in years, and therefore both lack many of the newer CSS properties.

In my search for a more modern bundle, I found CSS3, which had everything. The readme mentioned support for cssnext, but I just wanted my SASS to look pretty, so my first attempt at using it was to just associate all of my SCSS files with it. It did a reasonable job of highlighting, except for one small thing.

Do you see? In SASS I’m allowed to nest like the example on the left, but the CSS3 bundle is using proposed W3C specifications for its rules, therefore nested items need to be preceded with an ampersand. Interestingly I could also use the ampersand in SASS, because it would do the same thing, but it got me to thinking, why not go with the what will eventually become an actual standard? Why use this metalanguage, when I could start using the real thing?

What’s the difference? Well, for starters this would give me an opportunity to use syntaxes that I might be using in the future. Also, it would give me insight into the direction of the language, potentially allowing me to provide feedback. But the main reason is that it feels better to me to use a standard. It’s the same reason I never got into Coffescript.

The Setup

It was overall quite simple for me to get up and running with PostCSS. While it did require finding quite a few more packages than just SASS, now that I’m up and running, I don’t feel the configuration was any more difficult than SASS was at the beginning.

The first package I started with was cssnext. This provided me with the bulk of all the features I was using in SASS, but in PostCSS, and using a standards-based syntax. Nesting is built-in, I just need to use an ampersand, or for more advanced selectors, there’s an @nest rule. This package also happens to include autoprefixer, which I was using before as well.

Custom media queries become @media, and variables and mixins just have to be applied in the :root element now, and get used with a slightly different syntax.

Getting the build process to work the way I wanted required a few more plugins. Cssnano did the majority of it, but I also needed to import files into a single output, so that was accomplished by postcss-import.

@extend is a proposal for CSS, but the cssnext project doesn’t include it currently, so I have another plugin for that as well.

One really cool thing I wasn’t doing before with SASS is the css-mqpacker plugin, which pulls all of my nested queries into a single block, which can be a pretty big savings for larger projects.

My gulp process now uses gulp-postcss, and I’ve moved all the postCSS related plugins to a separate file, so I can just copy and paste it going forward.

gulpfile.js

gulp.task('postcss', function () {
  return gulp.src('./postcss/styles.css')
    .pipe(postcss())
    .pipe(gulp.dest('./build/css'));
});

postcss.config.js

module.exports = (ctx) => ({
  from: ctx.from,
  to: ctx.to,
  plugins: {
    'postcss-import': {
      path: 'postcss'
    },
    'postcss-cssnext': {},
    'postcss-extend': {},
    'css-mqpacker': {
      autoprefixer: false
    }
  }
})

Overall I’m quite happy with the new setup. It was mostly a lateral move, I didn’t gain a ton, or lose anything, but I do enjoy the fact that I’m now writing in an industry standard. It’s also gratifying to think that in the future, this CSS might just work as is, no build step required!