Do not drop Sass for CSS

Do not drop Sass for CSS

I was just reading a post by Chris Ferdinandi – Is it time to drop Sass? – I want to speak on the topic.

Why drop Sass?

Chris is known as the “vanilla JS guy”. He favours using JavaScript and eschews many tools. This contrarian opinion is important in a noisy frontend world that is constantly pushing the use of particular frameworks and tools.

Chris says the following in his post:

I’ve been using Sass for a decade, but recently, I’ve been wondering if it’s time to ditch it and move on.

The thesis in the article is that CSS now has almost every feature that he uses from Sass. Nesting has been added to CSS recently and this prompted the article, I guess. One exact feature that is missing for Chris is the @import declaration to bundle styles from different partial files into a single file.

Chris favours using the ESBuild bundler to work out the shortcomings. ESBuild can bundle CSS files into a single CSS file. ESBuild can transform your natively nested CSS to “flat” CSS – this is important since nesting is not in Firefox currently. Therefore, with the aid of ESBuild, Chris has feature parity for his usage of Sass. The other Sass features like mixins and inheritance do not appeal to Chris.

Frankly, none of these seem like deal breakers. I think it’s time to go vanilla CSS

The thrust of what Chris is saying is that CSS has grown a lot and this reduces the need to reach for a CSS preprocessor.

Dave Bushell wrote about CSS nesting in a recent post too, and he also concluded that he no longer needs Sass because he has the features he needs in CSS now. He said the following:

Goodbye Sass!

With these updates I no longer need the Sass preprocessor. A little sad to let such a useful tool go. I’ve been using Sass for longer than I can remember. […] With calc(), custom properties, and now CSS nesting, my need for Sass is all but gone.

Dave is using Post CSS to produce unnested CSS that works in all browsers.

Let’s look at it from the other side.

Why shouldn’t you drop Sass?

I want to zoom out for a moment and make a more general point about choosing technologies in the frontend world.

A corollary of “dropping tools” thinking is that it portrays technologies as disposable commodities. It projects “Yes! Finally CSS has the best of Sass. Let’s chuck Sass”. The perception is that you can switch quickly, and at a low cost.

Another facet of this is that choosing a technology is often construed as being mutually exclusive: Sass or CSS. This can led to bad decisions. Do you use the same technology on every project?

I see style technologies, whatever format you write your webpage styles in, as a major building block on the web. You don’t replace the bricks in your house, just because another brick offers similar benefits at a slightly cheaper price. Why would you think that way about CSS?

Progression of one technology does not mean that you will stop using another technology in a punctuated manner. Replacing something like Sass can be a big undertaking. It is wise to at least understand the differences between Sass features and the equivalent CSS features before you transition! How much work can it really be?

As the Sass blog points out: native CSS nesting is subtly incompatible with Sass nesting. You cannot use native nesting in a Sass file. This makes a progressive switch difficult. You will need to replace every Sass file to make a complete transition. It is not just a find-and-replace operation across files because of the subtle differences with nesting. When David Bushell replaced Sass with CSS on his personal website, it required him to restructure his list styles.

You need to consider the others bits of Sass syntax you have used in a project and decide how you will port those styles. For example, Sass variables and CSS custom properties are intrinsically different. Sass variables are imperative, which means if you use a variable and then change its value, the earlier use will stay the same. CSS variables are declarative, which means if you change the value, it’ll affect both earlier uses and later uses. You will need to review your variables to ensure that the result is the same.

Also, it is easy to forget that Sass offers some niceties that you may think are in CSS but aren’t! Jim Nielsen discussed how much he misses single-line comments from Sass recently in a post:

Then Brad Westfall reminded me of a Sass feature that, while small, is probably the one I miss the most every single time I write vanilla CSS: single line // comments.

You will need to convert single-line comments into multi-line comments to be valid CSS! 😰

And what is the benefit of transitioning from Sass to CSS on an existing website exactly?

In the short-term, the only significant benefit may be that your build process is simplified. There is a cost to get there.

If you are making a new website, then it is a different proposition. You have less constraints and more freedom. Choosing a CSS preprocessor or CSS is open. Your choice is contingent on other decisions, and other tools you may wish to use. If you are trying something new, like using a different feature set or alternative style technology, it will take you longer. You should budget time for that.

If you want to build a performant website these days, you are likely to have a build step with some tools. It would be great not to need any tools, but to scale a website, it is difficult to forgo all tools. That’s why it may seem like a step forward to use one less tool in your toolchain. I think that this is the primary benefit people are chasing. I think that the panacea of zero tooling can be blinkering.

Ask yourself what is the benefit of making a change?

Often, substituting tools does not benefit the user. The payoff is on your side. The payoff for you should be large enough that the user sees a benefit because it enables you to deliver in a superior way. In some cases you are just learning to do the same thing, another way, somewhere else. People gloss over the time required to learn the “new way” properly. This is time that could be spent shipping features.

Also, if you think tools like Sass are disposable, you may well repeat this process again soon for a similar case. When do you say: “No, I will stay on this course”. Wisdom is knowing what to overlook.

My question to you is it better to drop a tool, or is it better to drop this mindset?

Reminiscent of jQuery

The story of jQuery is analogous to this story with Sass. jQuery helped usher in an era of building reliable websites and web applications. It provided a consistent cross-browser API for working with the DOM. It eventually led to part of the API being adopted by ECMAScript. We can thank jQuery for querySelector().

When React was taking over the frontend world, jQuery was treated with ire in some quarters. A view developed (pardon the pun) that if you are using imperative style of programming in the browser that you are a chump. Using jQuery and React were seen by some as mutually exclusive decision. You are either a trendy declartive cat (React camp) or a churlish imperative dinosaur (jQuery). It had a tribal aspect to it. And it had the capriciousness of fashion – this season we are rocking React dungarees.

React and jQuery are different. You could build web interfaces with both. However, jQuery had a wider application, and it was a product of its time. It was not designed to solve the problem space of complex state and user interaction. It was concerned with improving DOM manipulation, animation, events, and AJAX in browsers. People built tonnes of utilities and widgets using jQuery because they wanted a pleasant API and things to work everywhere. It gave superior interoperability. The web platform did solve many interoperability issues at time went by.

Understandably, jQuery is not used by people very often to build user interfaces now. People chose UI frameworks for that task instead. I think that jQuery was brought up in conversation alongside React in that era because of their mammoth popularity and wide adoption, rather than as a thoughtful debate on how to build great web applications. Now that people’s first choice for building user interfaces is React, you find some people clawing at React for being too bloated, being all about SPAs, and so on! It’s a peciular cycle.

Today, jQuery is still used a lot. People did not just rebuild everything that used jQuery because it was no longer needed. According to W3techs, as of August 2022, jQuery is used by 77% of the 10 million most popular websites. I do not know how reliable that figure is, it is more than I expected, but the point I am making is that technologies stick around longer than people think, or openly admit. For some projects, it is probably marked as technical debt, and will be removed when there is an opportunity to do so.

Whatever your thoughts on Sass is, it is worthwhile to think of Sass in a similar vain. Don’t make it a popularity contest, or a tribal conflict on using one or the other. Recognize what technologies are good at and use them accordingly. If you want to make a change, then realise it comes with a price.

Closing thoughts

I think that you should choose the tools that fit your project requirements, that produce a great outcome for the user, and that work best for you.

I would encourage you to drop the “either/or” mentality around technologies. Don’t talk about dropping tools, talk about preferring a tool. Maybe, one is more suitable for a certain task, type of project, or methodology.

Let’s focus the discussion on why you would choose one thing over another with appropriate context and nuance. Recognize that switching from Sass to CSS has costs and benefits on existing projects, for green field projects you have a lot more latitude.

Brad Frost expressed similar thoughts in a Twitter thread recently when he made a one-page website with HTML and vanilla CSS, which I will paraphrase:

I’ve always seen a lot of all-or-nothing zealotry on both sides when it comes to tools and abstractions. Going without any sort of tooling/abstraction is tedious and inefficient. Going all in on tooling/abstraction is like taking a firehose to a teacup.

Every project has different needs that influence what/how much tooling/abstractions are necessary. My biggest piece of advice is challenge all-or-nothing thinking and be pragmatic about it all.

CSS and CSS preprocessors have a common purpose, but they also serve different needs. Sass is a superset of CSS, similar to TypeScript and JavaScript. It has a compile step that offers things that CSS does not. CSS preprocessors are great at avoiding repetition and expressing more complex design patterns. CSS preprocessors can create new features that do not require browsers to implement anything. They can be a vector for innovation, and they continue to evolve.

CSS has come a long way. Over time, we are able to achieve more without tools, but it is a process of evolution. Keep in mind that nesting being adopted by CSS is partly due to the success of the feature in Sass. Let’s give tools their dues and not be signing their death certificates when other tools adopt some of the things that made them great.

I do not see myself replacing Sass in existing projects soon. I will consider CSS in a different light for new projects going forward as it is growing more capable. That’s all good in my book.