DEV Community

Cover image for Goodbye SASS 👋, welcome back native CSS
Karsten Biedermann
Karsten Biedermann

Posted on • Updated on

Goodbye SASS 👋, welcome back native CSS

Sass has established itself as a powerful preprocessor installed locally, forming the backbone of my projects for over a decade. It enabled me to efficiently organize scalable and stable CSS packages. Even today, I still consider Sass to be an extraordinarily powerful tool. Yet, as we step into the year 2024, it's undeniable that CSS has undergone rapid development. Features that were once unique to Sass are now natively integrated into CSS, including variables and the latest highlight: CSS Nesting.

Variables

Defining variables was long seen as a unique strength of SCSS, allowing for the centralized management of many properties, a feature sorely missed in CSS for a long time. Today, however, variables can also be defined in CSS in a manner similar to Sass. A significant difference, however, is that Sass variables exist exclusively within the preprocessor context, while CSS variables can be used in the browser and even dynamically overwritten via JavaScript.

:root {
  --button-padding: 10px 20px;
  --button-bg-color: #007bff;
  --button-text-color: #ffffff;
  --button-border-radius: 8px;
}

.button {
  padding: var(--button-padding);
  background-color: var(--button-bg-color);
  color: var(--button-text-color);
  border-radius: var(--button-border-radius);
  border: none;
  cursor: pointer;
  transition: background-color 0.3s;
}
Enter fullscreen mode Exit fullscreen mode

CSS Nesting

The ability to define the style rules of one element within another significantly simplifies writing CSS. Instead of repeatedly using the same selector for subordinate elements or pseudo-selectors, nesting allows grouping these within a parent selector. This technique leads to a clear, hierarchically structured, and thus more efficient codebase.

With browser support of over 84% for CSS Nesting and 86% for the Nesting Selector, this technique is becoming increasingly accessible.

.blog {
  position: relative;
  padding: 1rem;
  background: var(--neutral-100);

    .blog-item {
      border: 1px solid var(--neutral-200);

      & span {
        font-size: 1rem;
      }
  }
}
Enter fullscreen mode Exit fullscreen mode

The :is Pseudo-Class

The :is pseudo-class revolutionizes the selector concept by accepting a list of selectors and styling all elements that match any of these selectors. This greatly facilitates the selection and styling of elements in the DOM.

:is(selector1, selector2, selector3) {
  /* styles */
}
Enter fullscreen mode Exit fullscreen mode

Instead of long selector lists, you can use :is() to improve readability while avoiding a long selector.

The : has() pseudo-class

The CSS pseudo-class :has() provides a powerful way to select an element based on its descendants, similar to the application of conditional styles.

.hero:has(.hero-button) {
  background-color: var(--accent-50);
}
Enter fullscreen mode Exit fullscreen mode

Container queries

Container Queries are considered the most significant innovation in web design since CSS3. They expand the concept of Responsive Design by allowing elements to adjust based on the size of their containers. This technology enables the design of an element to dynamically change depending on the context, leading to a more flexible and adaptive design.

.component {
  --theme: dark;
  container-name: fancy;
}

@container fancy style(--theme: dark) {
  .fancy {
    /* dark styles. */
  }
}
Enter fullscreen mode Exit fullscreen mode
.parent-container {
  container-type: inline-size;

  .headline {
    font-size: 2rem;
  }

  @container (width >= 720px) {
    .headline {
      font-size: 2.5rem;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

If the container fancy have the variable --theme: dark, add the following CSS.

Cascade layers

With cascade layers, we can avoid the nesting of classes, IDs, etc. for higher specificity by assigning our own layer (layer). Using the @layer at-rule and layered @imports, we can build our own layers of the cascade - from low-priority styles like resets and defaults, through themes, frameworks, and design systems, to the highest priority styles like components, utilities, and overrides. Cascade layers provide more control.

@layer utilities {
  .button {
    padding: 0.5rem;
  }

  .button--lg {
    padding: 0.8rem;
  }
}
Enter fullscreen mode Exit fullscreen mode

Future of SASS

Does this mean Sass has become obsolete? Not at all. Mixins and functions, such as the conversion of pixels to rem, remain irreplaceable advantages of Sass. Nevertheless, I have decided to forego Sass for most of my projects. Instead, I use predefined code blocks and packages in my Sublime Editor, which has significantly improved my workflow.

Goodbye SASS?

I truly believe that in 2024, the benefits of Sass, including installation, usage, and compilation issues, no longer justify its use. The scalability and user-friendliness of modern CSS make it possible to do without additional tools.

My Themex project demonstrates how powerful the combination of new CSS features can be: https://app.themexproject.com

With the advancement of CSS, I look forward to implementing small and large projects directly and straightforwardly.

Goodbye Sass, and thank you!

Image description

Top comments (57)

Collapse
 
sucodelarangela profile image
Angela Caldas

I love pure CSS, but I still love using Sass for its mixins, functions and extends. Also, nesting in Sass is a little better than nesting in CSS when you use BEM in your projects, for example:

.block {
  // in Sass you would break the class name like this:
  &_element {
    // this would not work with CSS nesting
  }
}
Enter fullscreen mode Exit fullscreen mode

But I am eager to be able to do this and more on CSS again! Thanks for the article!

Collapse
 
link2twenty profile image
Andrew Bone • Edited

One thing I've starting doing in my code bases is replacing the M in BEM to use has where possible.

<button class="btn">
  <span>
    First Button
  </span>
</button>

<button class="btn btn--with-icon">
  <svg height="1em" width="1em">
    <!-- some svg code -->
  </svg>
  <span>
    Second Button
  </span>
</button>
Enter fullscreen mode Exit fullscreen mode
/* tradition BEM */
.btn {
  background-color: tomato;

  /* this only works in SASS */
  &--with-icon {
    background-color: lime;
  }
}

/* BEM with has */
.btn {
  background-color: tomato;

  /* this works in vanilla CSS!! */
  &:has(> svg) {
    background-color: lime;
  }
}
Enter fullscreen mode Exit fullscreen mode

I still use SASS and BEM commercially but these little steps closer to regular CSS can only be a win in my opinion.

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

This is a good example how you can transform from scss to css. Personally, I haven't used BEM for a long time. In general, I think it's good to break with conventions, especially when it obviously prevents you from trying something new.

Collapse
 
sucodelarangela profile image
Angela Caldas

Nice! Thanks for sharing this approach!

Collapse
 
thomasbnt profile image
Thomas Bnt ☕ • Edited

Yes! I'm still using SASS because BEM is powerful to write good code. But I will try CSS3 with news features likes @container and @layer, seems nice!

Collapse
 
sucodelarangela profile image
Angela Caldas

I definitely must try the features you mentioned since I've only read about them!

Collapse
 
maxart2501 profile image
Massimo Artizzu

Many of the latest advancements in CSS help you ditch BEM for something much less verbose. Encapsulated styles (especially with @scope or a shadow DOM), or @layers, will definitely help you with that.

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

I agree! In some cases, it looks better in SASS, especially if you use BEM. As always, it's a compromise 😊.

Collapse
 
durodolafemi profile image
Oluwafemi Durodola • Edited

But will this work?

.block {
    //...
    .block_element {
        // ...
    }
  }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
sucodelarangela profile image
Angela Caldas

Yep, this works. The syntax I used doesn't.

Thread Thread
 
link2twenty profile image
Andrew Bone

The main different between these 2 is specificity.

.block {
  /* anything here has a specificity score of 10 */

  &__element {
    /* anything here has a specificity score of 10 */
  }
}

.block {
  /* anything here has a specificity score of 10 */

  & .block__element {
    /* anything here has a specificity score of 20 */
  }
}
Enter fullscreen mode Exit fullscreen mode

Having higher specificity means things are harder to override later and, in some cases, leads to the dreaded !important

This example isn't too bad but the further you nest the more likely you are to have run away specificity.

Thread Thread
 
sucodelarangela profile image
Angela Caldas

Thanks for sharing this specificity issue, I wasn't aware!

Collapse
 
latobibor profile image
András Tóth

I fully agree with you. However the more CSS can do from SASS the less any transpiler need to work, so the result will be closer to what you actually wrote. That's a good thing in my opinion.

Collapse
 
sucodelarangela profile image
Angela Caldas

Yeah, it is certainly a great thing, I agree with you, and I hope CSS gets even more powerful. I really enjoy using CSS, but at work, we still use Sass

Thread Thread
 
latobibor profile image
András Tóth

Well it's a great tool, so it does not sound so bad as forced to write CSS-in-JS or to be barred from writing CSS because of a utility based framework.

Collapse
 
senseijurado profile image
Convergente Studio

Yeah, mixins are one of the best things on Sass, cuz this and other stuffs is why i still using even nowaday

Collapse
 
link2twenty profile image
Andrew Bone

I'm really looking forward to reusable functions and mixins. They're a little ways off yet but that doesn't stop the hype 😅

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

Ohhh yes! That would be so great!

Collapse
 
senseijurado profile image
Convergente Studio

Oohhh the great Andrew Bone, such a famous person known in Twitter, yeah I really agree, but Sass still being a great, despite of new CSS modern in 2024

Collapse
 
mindplay profile image
Rasmus Schultz

Modern CSS is awesome - but it's a bit late to say goodbye to SASS, I think.

By now, most software uses a component-oriented UI library of some sort (React, Svelte, Vue, Solid, etc.) and the question facing most developers isn't really SASS vs CSS anymore - it's more like SASS/CSS vs some sort of CSS abstraction... Emotion, Panda, StyleX, Tailwind, etc.

While CSS has caught up with most of the things we needed SASS for, the community has moved on from selectors to inline styling approaches, which just generally works better with components.

Remember when SASS was the brand new shiny, and the nested structure of SASS promised to nicely mirror the structure of the HTML elements? Of course, this turned out to be a bad idea, because you end up with compiled selectors that are way too specific, and everything quickly stopped doing it. It was a lot of the initial appeal though, I think.

By now, the easiest, most intuitive, most straight forward approach, is to put your styles directly on the elements in your components. No more dead selectors getting left behind. No more searching through the DOM in devtools trying to figure out what's changing the color of that button. Where is that rule that makes it bold on hover? It's right there, on the button element - it isn't accidentally matching anything else, it isn't being accidentally overridden by a more specific rule, and so on.

The choice between SASS and CSS is easier than ever before. Just choose. It's not that important.

But now there are dozens of libraries and approaches to CSS-in-JS, utility CSS generators, inline CSS libraries, and on and on - that choice is harder than ever.

(I wonder if CSS will ever catch up with the need for inline styling?)

Collapse
 
ben profile image
Ben Halpern

I sign off on this

Collapse
 
latobibor profile image
András Tóth

Until we have what you said mixins, functions and extends we are missing one of the most important tool of clean coding: encapsulation of complexity. To be effective, you have to find the right properties that belong together and extract them into something meaningful, that is closer to the abstractions of the page.

But I do believe they can be incorporated into pure CSS. (As I think TypeScript at this point should be just there in browser, like how it works with deno).

Collapse
 
eshimischi profile image
eshimischi

Typescript won’t be in browser, because at the end it converts into JS, which is deno doing too. TS is just a superset

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Does this mean Sass has become obsolete? Not at all. Mixins and functions, such as the conversion of pixels to rem, remain irreplaceable advantages of Sass

Irreplaceable? Far from it! Native CSS is getting functions and mixins too relatively soon; the discussion around the spec is still ongoing, but it is very unlikely to just die out. SASS will eventually just be obsolete.

Collapse
 
karsten_biedermann profile image
Karsten Biedermann
Collapse
 
smart_egg profile image
Dmitriy A.
  1. :has() is great! We are using it for a while now.
  2. Nesting is one of the most crucial part of SASS, not sure if cascading can replace it though 🤔
Collapse
 
karsten_biedermann profile image
Karsten Biedermann

Maybe not replace it. I think some people will continue to use Sass. However, I believe it's beneficial to occasionally question the way we write CSS. There have been times when I found myself complicating things simply out of habit 😉.

Collapse
 
smart_egg profile image
Dmitriy A.

Agree, but SASS with proper linter is strict enough to keep CSS code streamlined

Collapse
 
shailennaidoo profile image
Shailen Naidoo

This is great but you would still need a preprocessor to ensure the newer version of CSS is backwards compatiable.

Collapse
 
link2twenty profile image
Andrew Bone

With browsers entering a new 'evergreen' phase this is becoming less and less of a problem. IE was an issue for a long time but with that gone most users will always be on, or close to, the latest release meaning we can improve our code bases at speed.

The new baseline initiative is a great rule of thumb, once it's green us that feature! 😅

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

That's exactly how I see it too @link2twenty

Collapse
 
sm0ke profile image
Sm0ke • Edited

cool

Collapse
 
jaloplo profile image
Jaime López

Congrats for the article. Very well written and really good discussion about it.

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

Thank you!

Collapse
 
miialainen profile image
Miia

Great update!

Usually can't use SASS in my projects as it is not supported any more in the CMSs I use. And nice to know that nesting support in pure CSS starts to be on a level where it is acceptable to be used!

Collapse
 
cyrilthomas1983 profile image
cyrilthomas1983 • Edited

What about if Developers makes any syntax errors. While using SASS the compiler throws error? What will be the scenario while using pure css

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

I use Stylelint in all my Projects to validate the CSS (or SCSS) code: stylelint.io

Collapse
 
vtnorton profile image
Vitor Norton

I only used SASS for nesting, nice to know that! Will do only pure css now (just because I don't need sass, but it's a great tool)

Collapse
 
peerreynders profile image
peerreynders

Keep in mind that native nesting behaves differently so some adjustments/trade-offs need to be made.

Collapse
 
krakoss profile image
krakoss

very useful information Thank you very much for this article

Collapse
 
d7460n profile image
D7460N

Going native is awesome.

Collapse
 
karsten_biedermann profile image
Karsten Biedermann

yeah!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.