Skip to main content
Dublin Library

The Publishing Project

CSS Is Learning From SASS

 

In 2023, Chris Coyier wrote SASS features in CSS where he explores the SASS features that have been adopted in CSS.

It's been a couple years so, in this post, I will explore how have the features in Chris's article evolved and what additional features, originally in SASS, have been added to CSS. We'll also look at some of the SASS features that are still not in CSS.

Some background #

SASS is a CSS preprocessor that extends the capabilities of CSS with features like variables, nesting, mixins, and more. It has been widely adopted in the web development community for its powerful features that make writing and maintaining CSS easier.

I used to love SASS and used it extensively in my projects but, over time, I found that many of its features were being adopted by CSS itself or had alternatives in CSS that made SASS less necessary.

SASS Features in CSS #

Feature CSS Version Date Introduced
Basic Math calc() 2012
Variables Custom Properties

Defined with --*
2016

Then it’s taken until this year for any more of Sass features to get gobbled up:

Feature CSS Version Date Introduced
Nesting Nesting 2023
Trigonometric functions Trigonometric functions 2023
Color Manipulation color-mix() 2023
Color Manipulation Relative Color Syntax
2024
Includes Constructable Stylesheets

Javascript feature
2019
Mixins / Functions / Extend Style Queries 2023

Behind a flag in all browsers
according to caniuse.com
Variable Logic @if / @else 2025

Only Chromium browsers at the time of this post
Random Specified in CSS Values and Units Module Level 5 N/A

Not supported in any browsers yet
Better defined Variables @property 2024

But there are some SASS features that don't have a direct equivalent in CSS yet, and may never have one. These include:

  • Single-line comments (//)
  • Loops (@for, @each, @while)
  • Logging of values to console (@debug)

We can simulate some of the loops (@for and @each), others are impossible to simulate without a preprocessor or Javascript.

Simulating SASS loops in CSS #

CSS does not have built-in support for the different types of loops available in SASS, we can simulate these loops with a combination of existing CSS features.

It is not possible to simulate the @while loop. We will look at how to simulate the @for and @each loops.

for loops #

To simulate a @for loop in CSS, we can use CSS variables and inline styles to create a series of elements with different styles based on a counter.

We first define a series of CSS variables inside inline styles on the HTML elements.

For the example below, we use sequential values for the --i variable to represent the loop index; we can change these values as needed.

<div class="card" style="--i: 1;"></div>
<div class="card" style="--i: 2;"></div>
<div class="card" style="--i: 3;"></div>

We can then use the variables in the CSS to apply styles based on the counter value using the calc() function.

.card {
  border: calc(var(--i) * 1px) solid black;
  border-radius: calc(var(--i) * 5px);
  height: calc(var(--i) * 20px);
  width: calc(2rem * var(--i));
  margin-block-end: calc(var(--i) * 20px);
}

each / for-each loops #

This SCSS code will generate a series of classes for different button variants.

$colors: primary, success, danger;

@each $color in $colors {
  .button--#{$color} {
    background-color: var(--#{$color}-color);
  }
}

This type of loop can be emulated with data attributes in the HTML and attribute selectors matching the data attributes in the CSS.

First, instead of adding a list to a variable like we do in SASS, we add data-variant attributes to the HTML elements:

<button data-variant="primary">Primary</button>
<button data-variant="success">Success</button>
<button data-variant="danger">Danger</button>

Then, use attribute selectors in your CSS to target each variant. This approach neatly emulates the logic of the @each loop.

/* Define color variables */
:root {
  --primary-color: #007bff;
  --success-color: #28a745;
  --danger-color: #dc3545;
}

/* Style based on the data-variant attribute */
[data-variant="primary"] {
  background-color: var(--primary-color);
}

[data-variant="success"] {
  background-color: var(--success-color);
}

[data-variant="danger"] {
  background-color: var(--danger-color);
}

Edit on Github