
Stepping Away from Sass - spking
https://cathydutton.co.uk/posts/why-i-stopped-using-sass/
======
bbx
The case for CSS variables is interesting. I'm still trying to figure out the
best way to integrate them with a CSS framework I created, called Bulma:
[https://bulma.io/](https://bulma.io/)

There's a few ways to combine Sass variables and CSS variables:

    
    
      - make all Sass variables available as CSS variables as well, so $primary will also exist as --primary  
      - assign a CSS variable to a Sass one: $primary: var(--red)
      - assign a Sass variable that was defined as a CSS one: $red: var(--red) and then $primary: $red
    

Color functions are one aspect that isn't well supported yet by CSS only.

There's also a more "philosophical" question: why offload the variable
resolution to the client side when it can be done at compilation time? If
you're not gonna update a variable's value at runtime, it doesn't really need
to be available as a CSS variable.

It's like single page apps that always render the same content, and are better
off rendered once on the server side and delivered as static HTML, instead of
being rendered thousands of times by each client.

But to be fair, CSS variables have other benefits, like creating color
variations very quickly:

    
    
      // Sass
      .is-success
        background-color: $green-invert
        border-color: $green
        color: $green
        &:hover
          background-color: $green
          border-color: $green-invert
          color: $green-invert
        &:active
          background-color: $green
          border-color: $green
          color: $green-invert
    
      // CSS
      .is-success
        --color: var(--success)
        --invert: var(--successInvert)
    
    

Even with CSS variables, Sass still has a lot of benefits listed by other
commenters here, like reusable mixins and nesting. And one of my favourites:
@extend!

~~~
seibelj
I just want to say thank you for bulma, it is a top notch project and I
recommend it to everyone.

------
statictype
Does a preprocessor really complicate the workflow?

Variables are still new and not fully supported.

Being able to nest css selectors is major win for me.

Reusable mixins is another.

I just don’t see a compelling enough use case today to switch to pure css for
non trivial applications.

~~~
marcus_holmes
>>Does a preprocessor really complicate the workflow?

I've just spent yesterday getting sass to work with my Golang project.

I used to have a nice simple makefile task, that compiled the project (in a
split second) and launched it on localhost so I could find out where the
problems were. My only dependency was the Go compiler. If I changed the css,
the next page refresh sorted it.

Now I have a "sass watch" task, which compiles the scss to css. But that
requires node.js, and npm (there are golang scss compilers, but all of them
are either not being maintained, or have problems, or only support older
versions of scss). I have to run this in a separate terminal so I can stop it
when I need to.

I've deliberately not looked at my global node_modules directory. If I don't
look, I don't have to worry about how many js libraries just got installed on
my machine, and I don't have to think about who's maintaining them, and if
they're now malicious. As long as sass only touches the css files, and css
isn't Turing-complete (yet), then I don't need to audit any of that, and I can
assume that it's not injecting malicious code into my application.

Though there are possible attacks on my site that could originate with code
injection from a $malicious_left_pad js library, even via css, but it's enough
of a stretch that my paranoia can live with it. I can check out the compressed
css every now and again and see that it's not importing anything it shouldn't,
and be reasonably sure that I haven't just compromised all my users' security.

So yeah, it's not so much that a preprocessor is a complication, it's that a
preprocessor allows a malicious package to compile whatever it likes into
files that I will then serve from my domain to my users, who trust that I'm
not serving them malicious files. That's policed not at all by npm, or any of
the package managers, who cheerfully assume that all javascript developers are
honest.

~~~
stephenr
Use sassc and call it from your makefile.

~~~
jayshua
Not sure what it's like today, but last time I tried to use sassc it was a
nightmare. The official repo was just the library with no CLI. I couldn't find
a CLI that didn't also require me to compile it myself. Very frustrating.

~~~
wutwut5521
You might be thinking of libsass. sassc is dead simple and solves all of this
users issues.

~~~
jayshua
Correct me if I'm wrong, but doesn't sassc require the user to compile it?

~~~
tangue
You're right, on OSX you can brew install sassc

~~~
marcus_holmes
there's a Debian package :) thanks for the tip :)

~~~
marcus_holmes
just got this working with fswatch and sassc, thought I'd feed back that this
is perfect, thanks :)

~~~
wutwut5521
Heh, I just woke up and read this and thought “well thats enough problem
solving for today” :) Glad we could help you avoid the hell that is adding npm
to a non-node project!

~~~
mercer
Another thank you from here! I've had to use node just for sass in the past
and this is a much nicer solution.

------
whoisjuan
I honestly have never seen the value in pre-processors when writing CSS. I
think they abstract a lot of low-level understanding of your UI and make your
stylesheets overly complex. They definitely keep things sane when doing CSS at
very large scale (for example dealing with color palettes, fonts, etc) but are
not that useful when you're writing different components with different
rendering needs.

Nowadays I just do functional CSS (Tachyons, Tailwinds, Fractures, etc). It
has some drawbacks but you can go faster and change things more atomically
without breaking everything when changing a class, and you have the safety
given by the fact that every property have the same level of specificity
(which can be overriden by JS generated style attributes, in case you need to
manipulate the DOM directly)

Also, you can address your rendering needs atomically which works very nicely
when you're writing components in isolation. They also are an excellent
approach when doing server-side rendering since you can store classes
combinations in variables that can be passed from one template to another or
used and overriden in the same template as it gets evaluated by the server.
It's almost like a pre-processor without the hassle of recompiling your
sheets.

~~~
nkozyra
> I honestly have never seen the value in pre-processors when writing CSS.

As mentioned, theming and consistent ux requires far less writing and copy
paste with a preprocessor than in pure CSS.

I think React's approaches make CSS feel simpler but often just sweep the
inefficiencies under the rug.

A lot of this is being fixed with CSS4, so these will go the way of jQuery.
And while you don't need jQuery today, it served as an important polyfill for
a long time.

~~~
scrollaway
> _A lot of this is being fixed with CSS4_

CSS4 won't have nesting. SCSS isn't going away as long as nesting isn't a
thing in native css.

(Also css variables are awful to use. Honestly, CSS-WG should have just copied
most of scss's syntax)

~~~
nkozyra
I agree about CSS variables.

I'm unsure about the merits of nesting. Tends to make for some hard-to-read
code.

~~~
frosted-flakes
Most nesting I do uses the '&' parent selector, so it's not "real" nesting.

    
    
      .a-long-class-name {
          background: firebrick;
          &:hover {
              background:  red;
          }
      }
    
    

This approach has some clear benefits (less verbose and it groups related code
together) with little or no downsides.

~~~
nkozyra
Same, but this can definitely get long, ala

& > div, & a, & a { &:hover } etc.

~~~
frosted-flakes
Your example is a bit confusing. This would be a more idiomatic way of writing
it:

    
    
      .some-class {
          > div, a {
              background: blue;
              &:hover {
                  background: red;
              }
          }
      }

------
dfabulich
A lot of folks here are saying that they couldn't live without nesting CSS
selectors.

FYI the CSS Working Group approved a working draft of native CSS Nesting last
month; it's in "stage 1."

[https://drafts.csswg.org/css-nesting-1/](https://drafts.csswg.org/css-
nesting-1/)

There's a PostCSS polyfill you can use for it today.
[https://github.com/jonathantneal/postcss-
nesting](https://github.com/jonathantneal/postcss-nesting)

~~~
stefanfisk
when I use sass nesting it's almost always to do BEM style selectors via `&-`,
which really is soo much easier to read than having to type the full selector
every time, especially when you have A LOT of components in a directory
structure.

sadly this use case seems to be missing from the coming spec :(

~~~
somefuckingguy
Agreed. This is trivial to add if you use postcss (postcss-nested)

~~~
type0
Correct me if i'm wrong but postcss is js or node.js only, where's sass is
trivial to add with any language.

~~~
MarvelousWololo
I'm not totally sure but I think that for Sass only you'd still need Ruby or
Node.

~~~
serial_dev
Sass has LibSass which is a C++ port of the Sass engine (which was originally
written in Ruby). There are wrappers available in many languages, such as Go,
Java, Node, PHP (and even Ruby, interestingly enough).

[https://sass-lang.com/libsass](https://sass-lang.com/libsass)

------
Waterluvian
I read somewhere a quote like, "a bad abstraction is worse than none at all."
And for that I'm always on the lookout for things that look the same but
aren't actually. Careful not to merge them via abstraction because they might
deviate heavily all of a sudden and now you have to refactor a lot.

CSS is the #1 place where I spot those cases. And I feel that Sass and other
CSS preprocessors mostly lend themselves to shooting yourself in the foot with
abstracting similar things that aren't actually of the same category.

~~~
gitgud
Well said, creating _good_ abstractions is hard and takes careful
consideration. Hopefully the abstraction has some kind of benefit; simplicity,
flexibility or extensibility. I've personally found SASS to be cumbersome with
the encouraged nested of CSS and tightly couples the CSS to the DOM markup.

A better abstraction in my opinion is a utility CSS library like
_Tailwind.css_. It feels strange at first, but compose-able _utility styles_
eventually feels like a good abstraction, with less shots to your feet.

~~~
type0
> A better abstraction in my opinion is a utility CSS library like
> Tailwind.css

Exchanging sass with postcss based framework in my book is _the worse_
abstraction for almost any purpose.

~~~
gitgud
Why is that? Have you used it for significant projects? I've found the
hierarchy of CSS classes and where they're defined (e.g. global or component)
become hard to to manage and refactor when you want to reshuffle components
around...

I feel postcss-based styling is simply more predictable and easier to
refactor. And the abstraction, which can be clunky at first, becomes a sort of
intuitive DSL which let's you develop faster...

------
_bxg1
The only thing I still couldn't live without is nested selectors. Writing
maintainable CSS at scale is impossible without them. I really wonder why they
haven't been made native yet.

~~~
digianarchist
PostCSS [0] can do this and is far easier to install.

[https://github.com/postcss/postcss-
nested](https://github.com/postcss/postcss-nested)

~~~
_bxg1
Not sure how the install could be easier than "get a single command line tool
and run it against your root source file". If you're talking about the Ruby
version, node-sass doesn't require any of those extra steps

~~~
digianarchist
Have you ever tried to get libsass installed on a CI server? Painful.

~~~
_bxg1
Nope, though you're generally supposed to use a project that _uses_ libsass
(of which there are many), not use it directly. If the issue is the binary
itself, then maybe the Ruby version is what you want after all.

~~~
digianarchist
That's not the point. Installing via a library is actually worse. NPM will
bypass proxy settings via the postinstall script.

My point is that the libsass library should be ported to WASM to ease the
installation in a CI environment.

------
notjustanymike
Everyone forgets that SASS is meant to be programmable CSS.

It has loops, functions, namespacing, arrays, maps, and tons of utility
functions (especially around color).

If you treat it as CSS+ then you're not really benefitting from it's true
potential.

~~~
jcr1488
> Everyone forgets that SASS is meant to be programmable CSS

That sounds like a solution looking for a problem... The vast majority of real
SASS I've seen has been much like the stuff this article mentions.

> If you treat it as CSS+ then you're not really benefitting from it's true
> potential

People aren't looking for "potential", they're looking for a way to accomplish
their design goals whilst keeping their stylesheets maintainable. The real use
cases where SASS is actually worth the complexity overheads are getting fewer
and fewer.

------
ethhics
Hi, undergrad here. That is to say, I’m not anything close to an expert in web
design, but just in the course of making a simple static website to show
recruiters I realized a lot of lessons like these about how modern HTML/CSS/JS
can really handle anything you throw at it without having to worry about
frameworks or precompilers. Sure, Bootstrap and SASS helped get a prototype up
fast, but I feel like that gain in productivity was wasted once I had to fight
the framework for the fine details, and just writing what I wanted in vanilla-
land ended up writing out the frameworks as a byproduct.

Is this a common pattern in industry as well?

~~~
mjlangiii
It is a bit of catch-22 IMHO, for some. If you're very experienced it is just
as easy to roll your own (although others may not onboard as quickly compared
to well known libraries). If you're not very experienced then if you try to
roll your own it may wind up being a mess. I'm in the middle and once I
understand a library well I know its limitations and use its components as
they were intended where I won't have to customize them too much, and roll my
own components for the rest. This largely sidesteps the issues I used to have
of wrestling with UI frameworks. I hope that helps.

~~~
ethhics
Certainly! I wanted to hear some viewpoints about full vanilla vs framework-
based development, and your view of grokking the tools and implementing what
it doesn’t cover is a great one to consider.

------
kbody
I'm quite surprised by the number of comments on Sass/CSS pre-processors being
of little to no value while we have created a huge complicated Frankenstein
mess with webpack/React and the rest.

~~~
throwaway66666
I am quite surprised at how the wheels have turned. I remember a year ago I
was interviewing people and each single candidate listed SASS as a skill, and
almost everyone during the interview claimed its their preferred method of
working. (my team so far has been using plain css and are happy with it, so
that surprised me a lot back then).

Is it considered bad practice now? How did it rise so quickly, how did it fall
so quickly, what's going on in the web dev world?

~~~
everdev
Sass and other CSS generators were useful a few years ago for rapid code
generation. However, CSS has caught up as have editors and it's hard to see
what real advantage Sass has today.

Some novel things like a primaryColor variable to easily adust your theme is
easily replicated with a traditional find/replace.

The fewer frameworks / compiles-to X languages you have to learn the better.

IMO, a little redundancy is better than a little complexity or a little
dependency.

~~~
intertextuality
Using a find and replace instead of a variable holder is extremely bad
practice. I should not have to copy/paste my site’s brand colors every time.

The original reason I switched was for nested structures so I could stop
repeating myself. E.g.

div {

    
    
      &:hover {}
      .class ul {}

}

This made it much more pleasant to write in sass.

The other thing is mixins. If vanilla css doesn’t support this then it’s still
a no-go.

Lastly I’m confused why sass of all things is an issue. It’s basically css,
and very lightweight. You just add one step in your preferred build tool to
transpile sass -> css. “vanilla is magically better” is not an argument.

~~~
everdev
I used to write only in Sass for these same reasons, but switched back to CSS.

CSS now has variables (if you really need them -- chances are you don't).

The redundancy of writing a selector multiple times is sightly annoying, but I
don't think it rises to the level of value I need to include a new dependency
in my app or build pipeline.

~~~
intertextuality
That still doesn't account for mixins, which turn out to be very handy. Some
examples here.[0]

[0]: [https://css-tricks.com/custom-user-mixins/](https://css-
tricks.com/custom-user-mixins/)

These are preferable because you can compose them as needed for elements,
instead of having to make extra classes.

> CSS now has variables (if you really need them -- chances are you don't).

I fail to see how you could -not- need variables. Not many, mind you, but
using none at all boggles the mind. For starters, DRY code is fairly
fundamental. When you update a referenced variable you only need to do it in 1
place. Relying on "find and replace" leads to "oops I accidentally missed one,
now we have a bug that could have been totally avoided".

It also helps with consistency for site theming/branding. You can define
$primaryColor, $primaryHighlight, $secondaryColor, $textColor,
$backgroundColor, etc, and reference these down the line instead of
copy/pasting and getting bugs if the specs change.

~~~
boomlinde
_> When you update a referenced variable you only need to do it in 1 place.
Relying on "find and replace" leads to "oops I accidentally missed one, now we
have a bug that could have been totally avoided"._

Isn't that the point of selecting classes in the first place? That said, I
understand the utility in using it for things like individual colors, as you
described.

~~~
intertextuality
Classes do suffice if you follow the convention of "small, atom-like css
classes". I personally hate this style and prefer compositional css classes
for a component or a structured object.

------
luckylion
What I _really_ love about sass is using [https://include-
media.com/](https://include-media.com/)

I hate writing media queries, but

    
    
      @include media("<desktop", ">tablet") {
      }
    

Takes most of the pain away.

------
jheriko
Hello "human centered designer, specialising in interaction design, HTML &
CSS"

Your font is too big.

~~~
seppin
Everything else v awkward as well

------
jayshua
I recently built a new website from scratch after about three years working in
other software areas. Found to my surprise that I came back with some very
different opinions about how CSS should be structured than I had in my web dev
days, and I didn't end up using SASS at all. Still think the code ended up
cleaner and more modular than what I wrote before using SASS. The only feature
I really missed was @extend, but making the code I would have put in the %
selector an actual class and using that in addition to a specialization class
in the HTML worked well enough.

------
namelosw
The biggest thing Sass annoys me is in Node.js environment, I have to choose
either node-sass which depends on native module which require extra
compilation or matched pre-built binary. Or I have to choose ruby-sass which
depends on a global installation of Ruby. Both of the options are brittle.

For SPA I found it's easier to use CSS-in-JS solution like styled-component or
emotion. Or for Typescript I just use typestyle.

For non SPA I usually go vanilla CSS for simple stuff and stylus for complex
stuff.

------
topicseed
Worked a lot with CSS for 10+ years and SaaS' nesting is amazing. I still have
no clue when to NOT nest, but oh well, it is so useful to componentize the
stylesheets.

~~~
kangoo1707
Nesting is okay for one-level.

However it violates the principle of least astonishment. How come a button
inside .header differs from the button inside a .footer, then where are the
differences defined, inside the button.scss or header.scss? Then one must take
into consideration CSS Specifility and sprinkle !important everywhere.

Instead, use modifier (in BEM) or create two buttons (.header-button and
.footer-button) or create 2 utility class (.is-header-btn, .is-footer-btn) or
just use TailwindCSS and you're good to go for all kinds of requirements,
without ever resort to !important

~~~
luckylion
> However it violates the principle of least astonishment. How come a button
> inside .header differs from the button inside a .footer, then where are the
> differences defined, inside the button.scss or header.scss? Then one must
> take into consideration CSS Specifility and sprinkle !important everywhere.

That's true. On the other hand, who is still trying to figure those things out
without using their browser's dev tools and source maps?

Using Sass also doesn't mean that you can't use two button classes or utility
classes.

------
bovermyer
Interesting. CSS has certainly come a long way.

I'll still use Sass for the convenience of nested selectors, though.

------
benfrain
Pedantic point. It’s ‘Sass’ and not ‘SASS’.

Sass certainly pushed things forward in CSS world. Without Sass and LESS,
Stylus et al. I am quite certain we wouldn’t have CSS custom properties and
colour functions. Great additions to the language.

That said, I left Sass specifically some years ago.
[https://benfrain.com/breaking-up-with-sass-
postcss/](https://benfrain.com/breaking-up-with-sass-postcss/)

Tangentially related — in terms of dealing with CSS tooling/output for large
projects with many devs I have found the PostCSS ecosystem indispensable.

I wrote this a few years back after setting things up with PostCSS at
bet365.com this way:
[http://ecss.io/chapter9.html](http://ecss.io/chapter9.html)

The good thing about PostCSS is you can reduce the features as CSS becomes
more capable and easily incorporate extra tooling like autoprefixer.

------
actionowl
I need more coffee, I misread "Sass" as "SaaS" until several sentences in...

> I also unintentionally, (at least at first) removed all traces of Sass from
> my codebase.

Especially this part, still thinking that was "SaaS" :)

