Why we abandoned SASS and switched to PostCSS in our Drupal theme
A few months ago at Zivtech, our team started to look at best ways to improve the performance of our theme and take full advantage of controlling our markup with twig. We had ported our D7 theme for Drupal 8 and added a lot of great functionalities, such as Pattern Lab, CSS regression tests, etc. We wrote our own utility classes, Mixins and SASS functions, integrated flexboxgrid, and used Gutenberg as a responsive typography system. While we had all that we needed, we still ended up with too much convolution in our process and bloated CSS bundles at the end of our projects.
While SASS has helped us tremendously and allowed fast paced development in the past few years, we lost track of our CSS output. It’s a common complaint about preprocessors, and if we take a closer look at the important CSS conventions we need to watch for (DRY, reusable, less specific, no deep nesting, etc.), I can see how we slowly drifted away from a rigorous implementation. There are several reasons for it, SASS not necessarily being the culprit. It is a very versatile tool, and as such, the responsibility falls on its user. The real question is how to implement a proper workflow that we can enforce as a team in order to:
- Deliver a consistent product
- Improve performance and quality
- Facilitate development among developers
The answer may be…write less CSS! Not LESS, less. Leverage TWIG to write or generate dynamic classes based on a solid set of utility classes. The concept is not new, but front-end Drupal developers have been burned by the lack of control of the markup for a long time. We don’t have excuses now, so let’s change our ways and enter the postmodern era.
What are the benefits of abandoning SASS in favor of writing vanilla CSS and post processing it?
I think there are good answers all over the web, but I’ll throw in my two cents. The most compelling argument for me resides in the limitations imposed by using vanilla CSS. By that I mean that the best solution will often reside in adding a utility class to your markup. Moreover, if no shortcut is available (using a @mixin, or worse, an @extend -- in which case you’ll most likely repeat yourself), you might actually LEARN something by having to create a template or write a preprocess function. You’ll eventually benefit from having this exposed for further modifications. You also won’t add unnecessary CSS, obviously.
You will also be more mindful of your specificity and probably the nesting of your rules. Long, extraneous selectors are bad for performance, therefore utility classes will come in handy again and be the preferable solution.
I think a clean looking SASS stylesheet can be misleading. I know I am very tedious with certain aspects of my code writing (indentation, line breaks, spacing, readability in general) but SASS is very deceptive in that aspect; the code rendered is a bundle that you rarely get to take a close look at. In other words, one clean @mixin line may result in 10 lines of CSS repeated all over your stylesheet. Or the five @extend you wrote will result in a giant multi-line selector that’s rather heavy on your browser (let’s remember CSS parsers read right to left).
You get the idea. We were seeking a process that actually reinforces good practice.
There are many PostCSS NPM modules available to port the same types of functions SASS handles natively. But apart from the mandatory @import we needed to be able to get a modular organization of our files, we didn’t want PostCSS to make the same mistakes that our SASS implementation was doing in the past.
By using a smart utility class system (we chose Basscss) and reworking our templates, we managed to reduce our theme CSS bundle file from 54k to 25k. That’s an improvement in itself for sure, but not as much as the exponential effect it will have on a finished website. By laying down a solid foundation and workflow we can ensure:
- A drastic reduction of the bundle size
- A clear, well defined system with understandable rules
- A way to allow our site builders to implement minimal styling (layout, spacing)
- A more manageable stylesheet structure for teams (by reducing the amount of tools)
- A thorough template based system in which developers have more control over markup and dynamic classes with native TWIG functions
Again, this is not a bashing of SASS, which is a powerful and very useful system of writing front end code. This is merely a recalibrating of our priorities, and a way to streamline our code and processes.
What we used
We stuck with gulp for our setup, and here’s the list of the plugins:
- BassCSS - We find it to be a very succinct, concise, and easy to work with CSS utility collection tool
- gulp-postcss - self explanatory
- postcss-cssnext - a great postcss plugin that bundles all of your extra PostCSS needs
- gulp-sourcemaps - we still want to map our CSS files for faster debugging
- postcss-flexibility - a polyfill for flexbox
- gulp-concat-css - bundle all your CSS files into one
- gulp-cssnano - for a clean, compressed bundle
- css-mqpacker - group your media queries together for better performance
- browser-sync - just because it’s an amazing piece of software
- gulp-css-info - super useful plugin to parse the CSS and create a searchable style reference doc - we turned this one into a CSS Info Drupal 8 plugin
A few other tools are being used to tie all these together, but you can find the full setup by downloading the theme on Drupal.org at https://www.drupal.org/project/bear_skin
Watch a video of the module in action.
Questions? Comments? Act below!