5

Official CSS Nesting – the last piece of the puzzle

 2 years ago
source link: https://benfrain.com/official-css-nesting-the-last-piece-of-the-puzzle/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Official CSS Nesting – the last piece of the puzzle

17.03.2021 0 comments
355 days since last revision. Details have probably changed.

Back in 2013 I wrote one of the first books on Sass, “Sass and Compass for Designers”. While I believe it is the best tech book I have written, I went into it knowing what a niche topic it was. It was far less popular than other books I have written but it was a book I wanted to write. At the time, as a CSS developer, I was giddy about what Sass allowed us to do and wanted other people to know about it.

Subsequently, in 2014 I came up with ‘Enduring CSS’, or ‘ECSS’ as it’s also known. A methodology that still sits behind the CSS for the World’s largest gambling application and gets used by scores of developers daily.

Now, perhaps it’s because it the problems it solves aren’t so widely applicable, or perhaps because I just don’t have the social clout to get it ‘out there’, but it’s kind of faded into relative obscurity. I think it’s a shame because I still see developers trying to solve the same problems that were solved 7 years back. Hey Ho!

Anyway. One of the core tenets of ECSS is the idea of a ‘single source of truth’ for each key selector in a code base. See here and here for more on that. The short version being that everything that happens to a selector is contained in a single set of braces.

You would write this:

.key-Selector {
    width: 100%;
    @media (min-width: $M) {
        width: 50%;
    }
    .an-Override_Selector & {
        color: $color-grey-33;
    }
}

And it would yield this:

.key-Selector {
  width: 100%;
}

@media (min-width: 768px) {
  .key-Selector {
    width: 50%;
  }
}

.an-Override_Selector .key-Selector {
  color: #333;
}

The takeaway here being there was a tooling dependency to allow authoring CSS in the requisite format. Now, even back in 2013/2014, Sass and PostCSS were pretty ubiquitous but there was still a little friction if you wanted to just throw up something in HTML/CSS using the ECSS methodology. Or for that matter, whatever other thing it was useful to do with nesting in pre/post processors.

What do I even need Sass/PostCSS for?

So, I absolutely relied on pre/post processors for nesting. Yet, even back then I very rarely needed mixins, and never used @extends and many of the more obscure Sass language features.

Sass style $variables were very useful in the past but I now rarely use them over CSS Custom Properties. Custom Properties took a while to arrive but boy did they make up for being late to the party – as part of the CSS language they are infinitely more powerful than Sass style variables plus malleable with JS too.

So, the only, and I mean the only, part of Sass/PostCSS I cannot live without still is nesting. Nesting related selectors to encapsulate the full ‘story’ of a selector is, to me, such a powerful concept.

Real CSS nesting

There have been discussions on getting nesting into the CSS specification going back years. Excitement would build and then die back down and I would resign myself to ‘one day’ getting it.

So imagine my excitement when Adam Argyle recently tweeted a link to the latest CSS Nesting Module draft Tab Atkins and he are working on.

Now, don’t get too excited. There are no implementations yet, and this currently, as far as I can gather, is a Chromium only affair; both Adam and Tab being Google employees.

Once more for the folks in the cheap seats, the draft explicitly states:

It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

However, don’t let that dampen our enthusiasm for what is virtually the same functionality we love in Pre/Post processors with an near as dammit syntax, hopefuly making its way, inexorably, to our browsers.

A syntax kind of/sort of just like you are used to

Section 2 of the draft describes the typical nesting syntax you will be used to seeing, like the example at the start of this post. You use the ampersand ‘&’ as a reference to the parent selector it sits within.

Worth noting however that if you are the kind of maverick that does this in Sass et al:

.key-Selector {
    width: 100%;
    .a-Selector_NowMoreSpecificThanItNeededToBe {
        color: #333;
    }
}

It won’t work. The selector would need to be ‘nest prefixed’ with an ampersand. So this would work:

.key-Selector {
   width: 100%;
   & .a-Selector_NowMoreSpecificThanItNeededToBe {
       color: #333;
   }
}

However, the thing I most want to do in vanilla CSS is this:

.key-Selector {
    width: 100%;
    .an-Override_Selector & {
        color: #333;
    }
}

And that isn’t possible in this specification either. This quote from the draft is a little bit ‘Inception’ so just do your best – I only needed to read it about 15 times 😀

To be nest-prefixed, a nesting selector must be the first simple selector in the first compound selector of the selector. If the selector is a list of selectors, every complex selector in the list must be nest-prefixed for the selector as a whole to nest-prefixed.

So, short version, Ben can’t have his ampersand at the end to encapsulate things. Does this mean my hopes and dreams have gone up in smoke?

The @nest rule

Thankfully there is the @nest at-rule. Because this can act as an unambiguous flag to the parsers it lets you do the kind of thing I’d like to:

.key-Selector {
    width: 100%;
    @nest .an-Override_Selector & {
        color: #333;
    }
}

That is going to work fine but you do need both the @nest and the &. More specifically, every nested selector will need a nesting selector (&). Needing the @nest is a bit of a pain; I’d be chuffed if the @nest wasn’t necessary but if it gets us over the line, it’s a small price to pay.

Maybe they could shorten or allow a shorter @n as well? Unlikely but just a thought.

Conditionals

The other essential application of nesting is to stick conditionals where they most logically belong. In more straightforward parlance – being able to nest media queries!

So while you can’t do exactly what you are used to doing in Sass, which is something like this:

.key-Selector {
    width: 100%;
    @media (min-width: 500px) {
        width: 50%;
    }
}

It’s only a stones throw away from something that would work:

.key-Selector {
    width: 100%;
    @media (min-width: 500px) {
        & {
            width: 50%;
        }
    }
}

Note the ampersand nesting selector in there again. Again not my 100% ideal but absolutely usable and sensible.

Summary and spread the word!

I’m looking forward to Nesting in CSS proper. Not just because of what it facilitates but what it means for the language. Tools like Sass pushed CSS on so much, and I’m hugely grateful they did. But it would be very liberating to not need them at all.

It will be a few years after nesting finally makes it into the browser before any of us could safely retire our pre/post processors. So while seeing this spec get some implementations won’t be the end for pre/post processors, it may, at least for me, be the beginning of the end. I’m aware that not everyone will feel this way. Plenty of folk I admire, *cough*Ana Tudor*cough* do things with Sass that won’t get any easier with vanilla CSS just because it has nesting. But for this author, it may well be the last piece of the puzzle.

And in my mind that won’t be a sad day for pre/post processors, it will be the vindication of their existence in the first place.

If this post was useful, Say thanks with a coffee. Every donation helps keep me going! 🙏


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK