1. Web Design
  2. HTML/CSS
  3. CSS

6 Preprocessor Features Coming to Native CSS

Scroll to top

Using preprocessors such as Sass, LESS and Stylus has always given developers more control over their stylesheets, but native CSS is gradually closing the gap. CSS features such as variables, calc and mixins are just the tip of the iceberg; let’s review what preprocessors are currently helping us with, and how native CSS logic is going to change how we do things.

Brother TypefaceBrother TypefaceBrother Typeface
Graphic from Brother Typeface on Envato Elements

The Age of Preprocessors

Language abstractions such as Sass, LESS and Stylus blew up developers’ worlds by giving them variables, mixins, functions, extends and much more. These preprocessors filled in missing features which CSS wasn’t able to provide. 

However, CSS should no longer be thought of as “logic-less” without the presence of intellect. With CSS on the move to refine itself, we’re already catching glimpses of the future—a future that will compete with preprocessors.

1. Mixin It Up

Typically we associate “mixins” with preprocessors, groups of CSS declarations which you can reuse throughout a project. A mixin can be used as a standalone helper, or you can pass values as arguments to make it extra flexible. 

Here’s a Sass @mixin example called font-size.

1
@mixin font-size($size, $base) {
2
  font-size: $size; // fallback for old browsers
3
  font-size: ($size / $base) * 1rem;
4
}

The above mixin will accept arguments for $size and $base, and it's used in an @include declaration with the ability to adjust arguments depending on the context.

1
/* Sass Call */
2
body {
3
    @include font-size(14, 16);
4
}
5
6
/* CSS output */
7
body {
8
  font-size: 14px;
9
  font-size: 0.875rem;
10
}

The result is a rem based value for font-size with a px fallback for browsers that don’t support rem. Preprocessor mixins like this have saved developers countless hours over the years.

Native CSS mixins are currently an editors' draft, but also have a working implementation in Chrome. If you’ve already played with CSS variables, the following snippet will look quite familiar.

1
:root {
2
    --pink-theme: {
3
        background: #F64778;
4
    }
5
}

Beware that the code above will most definitely make your syntax highlighter go bonkers. This way of writing a CSS mixin uses a new at-rule called @apply, similar to what we know in Sass as @include.

1
body {
2
  @apply --pink-theme;
3
}

Just as we’re familiar with Sass using @include, we could eventually have @apply for CSS!

Enabling the apply feature in ChromeEnabling the apply feature in ChromeEnabling the apply feature in Chrome

You can try this experiment for yourself within Chrome by enabling a flag under chrome://flags/#enable-experimental-web-platform-features.

2. Do the Math

Remember when preprocessors were the only style tools capable of mathematical gymnastics? Well, that isn’t the case anymore. With calc(), we can take those pesky numbers and mutate them into new values based on your desired arithmetic.

1
nav {
2
    margin: calc(1rem - 2px) calc(1rem - 1px);
3
}

This is the beauty of calc(); it finally extends CSS powers into the stratosphere. Prefer addition? Subtraction? Division? Multiplication? Calc can handle all that and more.

If you’d like to read more about calc()the W3C spec has everything you’ll need to make you drowsy and happy at the same time. Browser support is also rock-solid, according to Can I Use.

Calc supportCalc supportCalc support

3. Pass the Variable

Native variables for CSS are finally here. They’re a real and tangible option for developers, though it took some time to learn from preprocessors.

Here’s what Sass variable syntax looks like:

1
$spacing-unit: 20px;
2
3
main {
4
    margin: $spacing-unit;
5
    padding: $spacing-unit;
6
}

Sass variables are denoted with a dollar $ sign, but in CSS they look a bit different:

1
:root {
2
    --primary-color: skyblue;
3
}
4
5
nav.primary {
6
  background: var(--primary-color);
7
}

CSS variables are denoted with a double hyphen -- and are typically placed inside :root for global access, although their scope can be tightened by placing them within specific selector declarations.

1
div {
2
    color: var(--my-var, red);
3
}

Variables can even accept a fallback value if they aren’t yet defined, as is the case with the example above. Browser support isn’t bad either, with Edge showing partial support. The spec is also in the candidate recommendation stage for your reading pleasure.

CSS variables on Can I UseCSS variables on Can I UseCSS variables on Can I Use

4. Nest Building

Nesting is a feature in many preprocessors which allows you to place selectors inside an existing declaration. Typically, nesting in Sass looks something like this:

1
ul {
2
    margin: 20px auto;
3
    li {
4
        font-size: 12px;
5
        a {
6
            text-decoration: none;
7
        }
8
    }
9
}

Nesting can become unwieldy and get you wrapped up in a ton of trouble, resulting in impossibly long selector chains. For this reason, it’s advisable to stick to the Inception Rule and keep nesting to no more than three or four levels deep.

While nesting can be dangerous, it can also be handy if you take the time to be mindful. Here’s a sneak peek into how it could eventually look for native CSS:

1
/* CSS Nesting */
2
nav {
3
  color: #222;
4
  &.primary {
5
    background: maroon;
6
  }
7
}
8
9
/* Result */
10
nav {
11
    color: #222;
12
}
13
14
nav.primary {
15
    background: maroon;
16
}

Just as we’re accustomed to with our preprocessor allies, native CSS nesting lends us the same principles, but without the need to compile the language. There’s a draft spec by Tab Atkins on this very feature for Native CSS nesting.

5. Extend Rule

“Extends” are another way to pass properties and values around, sharing them between declarations. In Sass, we’ve become used to applying the following syntax:

1
.message {
2
  border: 1px solid #ccc;
3
  padding: 10px;
4
  color: #333;
5
}
6
7
.success {
8
  @extend .message;
9
  border-color: green;
10
}
11
12
.error {
13
  @extend .message;
14
  border-color: red;
15
}
16
17
.warning {
18
  @extend .message;
19
  border-color: yellow;
20
}

You can see that we start by defining styles for .message, and then offer three variants with different border-colors. Each variant first extends .message, thereby inheriting all its style rules, before changing the border color.

Identical syntax to the example above is what’s being drafted by Tab Atkins as another potential spec for native CSS. Whether or not you agree with extends (a feature whose benefits are hotly debated), it’s great to see CSS caretakers embrace ideas brought forth by preprocessors.

6. Your True Colors

If you ever find yourself using preprocessor color manipulation functions, you’ll appreciate this functionality in native CSS. The color-mod() function takes an existing color and applies zero or more “color adjusters” which specify how to manipulate the end result.

1
nav {
2
    background: color-mod(#79d3e2 hue(360) saturation(100%));
3
}

Development is in the early stages, and while there are polyfills available, syntax changes frequently (the current color-mod used to be color, for example).

Tyler Gaw made a really neat tool (colorme.io) that lets you experiment with all the possible color adjusters available.

colormeiocolormeiocolormeio
colorme.io

Spec for the color-mod() function is currently in draft mode through the CSS Working Group.

Closing Thoughts

In the same way that jQuery helped make the web better, so indeed have preprocessors when it comes to CSS. Languages like Sass have helped pave the way for new ideas and approaches not yet considered by the CSS spec authors. 

I hope the new features we’ve talked about inspire you to use them in your own work; I encourage you to consider using native functionality over a preprocessor whenever possible!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.