Native CSS nesting now supported by all major browsers!
Tags: css, webdev
Published: 2023-08-29 19:44:42

Today, [Firefox version 117](https://www.mozilla.org/firefox/117.0/releasenotes/) has been released, which adds support for native nesting of CSS rules! With that addition, all modern **desktop** browsers now support it! 🎉

![Firefox 117 adds support for CSS nesting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwlia2xnlsdf2p61q5ox.png)

Do keep in mind that there are some mobile browsers that do not yet support it. Together, these account for about 3% of the global browser market share.

Now that this feature is well supported, we can ask ourselves if using a CSS pre-processor is still worth the hassle.

But first, a quick refresher.

## CSS Nesting 

CSS nesting allows you to group related selectors together and potentially reduce the number of rules you need to write:

```css
/* CSS */
button {
   background-color: white;

   &.danger {
     background-color: red;
   }

   & img {
      width: 1rem;
      height: 1rem;
   }
}

/* HTML */
<button class="danger">I am red</button>
<button><img /></button>
```

It allows you to nest multiple levels, but please don't go overboard with nesting too deeply, as this adds up to the specificity of these CSS rules. This makes it hard to read and reuse your styles - nobody likes pyramids of doom! Deep nesting is simply unnecessary in most cases.

## Do you really still need a CSS pre-processor?

Many people use so called _CSS pre-processors_ such as [SCSS](https://sass-lang.com/guide/) or [LESS](https://lesscss.org/features/) that add fancy features to CSS, such as variables, mixins and functions, but they need to be transformed back to regular CSS during the build process of your app, so the browser can understand it.

The features they offer are:

- **Nesting** - There are only small differences between native CSS nesting and LESS/SASS. CSS is a little more strict, because you need to prepend every nsted selector with `&` and you need to define regular styling _before_ the nested styling.
- **Variables** - Native CSS variables have [good browser support](https://caniuse.com/css-variables) for a while now. The benefit of using native variables is that they are available at run time in your browser, which allows you to easily tweak them in your developer tools. 
- **Mixins** - This allows you to reuse a set of rules inside another selector. I never really found a good use case for mixins. They were available to me when I was still using Bootstrap with LESS, but using them seemed a little complex, because you always need to look up what they do and the resulting CSS output is not always clear. If you're thinking of using them for browser prefixes (e.g. `-webkit-transform`), I would suggest checking out [PostCSS autoprefixer](https://github.com/postcss/autoprefixer) instead.
- **Partials/Modules** - CSS has an `@import` rule that works well enough (at the cost of an extra HTTP request). Combine imports with [CSS layers](https://www.bram.us/2021/09/15/the-future-of-css-cascade-layers-css-at-layer/) and you have a pretty solid setup to modularize your CSS.
- **Functions** - These allow you to write CSS in a similar fashion as functions in other programming languages. I always found that they bloat your CSS output and they are hard to read as well. I would avoid using functions unless you have a really good use case for it.
- **Operators** - Need math in your styles? [CSS calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) gets the job done.

All in all, most features that pre-processors offer can nowadays be replaced by native CSS, so you can ask yourself whether an extra pre-processing tool in your stack is still worth it.

In large projects, it is still a good idea to use [PostCSS](https://postcss.org/), which will translate new CSS features to something that browsers understand today.