September 11th, 2023 × #css#frontend#webdev
CSS Nesting is Here!
Wes and Scott discuss the new CSS nesting syntax that is now supported across all major browsers. They cover how it works, best practices, use cases compared to Sass, browser support via transpiling, and more.
- CSS Nesting overview
- Ideal CSS nesting syntax
- How CSS nesting works
- When to use CSS nesting
- Avoid over-nesting selectors
- Ampersand parent selector
- Breakout selector with ampersand
- Element selectors don't need ampersand
- Sibling selectors with nesting
- Previous sibling selector
- :has pseudo selector with nesting
- Nesting media queries
- Nesting container queries
- Naming grid areas for reusability
- Browser support via transpiling
- Benefits over Sass
- Lightning CSS alternative
Transcript
Announcer
Monday. Mon Monday. Hey. Open wide dev fans. Get ready to stuff your face with JavaScript, CSS, node modules, barbecue tips, get workflows, breakdancing, soft skill, web development, the hastiest, the craziest, the tastiest web development treats coming again hot. Here is Wes, Barracuda, Boss, and Scott.
Announcer
CSD.
Wes Bos
Welcome to Syntax. This is the podcast with the tastiest web development treats out there. CSS Nesting is here, and we are going to tell you all about it, how it works, how to get it to work in every single browser, the gotchas to think about.
Wes Bos
And, like, shouldn't you not use that? So I put out a tweet the other day about CSS Nesting. It had landed in Firefox 117, which means that it is now in every single browser out there, and it can be compiled back to every all the way back to IE3 or something silly like that. So you can start using this today.
Wes Bos
But I got flooded with post CSS, right? Exactly. Yeah, exactly. A lot of people were like very angry about nesting, which I understand because they probably have dealt with a lot of Garbage code, and you probably are nesting more than you should, but it's still handy. And we're going to talk about why that's handy and and and whatnot.
Wes Bos
How are you doing today, Scott? I'm doing good, man.
Scott Tolinski
Doing super good. I'm ready to talk about nesting in, like you said, Garbage code? Yeah. You can you can look at garbage nesting code, and, you know, you can have bad feelings about nesting because of how hard it is to change anything, but, nesting when done right and, you know, use like a little bit a little bit of seasoning in your your feed. It's really well. It's really nice. Makes makes your work a lot easier sometimes writing selectors and stuff. But I'm doing good. Me, personally, I'm doing, You know, just just fill in fill in the flow of of all this stuff. You know? We're gonna be talking about Hack Week in the it. The, Tasty episode this week, and it feels really good to come back to actual work after hack week because hack week stuff is fun, but actual work is Fun and productive as well. So I'm feeling energized, and I'm feeling ready to go on some actual code stuff. How are you feeling? Good.
Wes Bos
I'm feeling great.
Wes Bos
Let's get on into CSS nesting. So first of all, this is very, very close to the Sass syntax.
CSS Nesting overview
Wes Bos
We had talked we've done a show about 2 years ago about the proposed syntaxes, and there was like a lot of like, that's kind of annoying. Do they really have to do that? And to our delight, almost all, if not all of those like, Sass is better have gone away, and the syntax is pretty much what you would expect from SAS with a couple of little things here or there. So I'm very happy with The end result of this nesting syntax because it's exactly what I would have hoped for. What what do you think about that? Yeah. This is
Scott Tolinski
Probably the ideal scenario for CSS nesting, which it really felt like it wasn't going to happen because that was the message was, hey.
Ideal CSS nesting syntax
Scott Tolinski
I know y'all want it, but it's not going to happen.
Wes Bos
So Yeah.
Scott Tolinski
Get over it already. And, I was very delighted when in fact, I I almost didn't believe it when people start talking about nesting as being like, oh, here, you can just do nesting like Sass. Now thinking yeah. No. It's it is Kinda like SaaS, but it's not quite it's not quite like that. You know? But I was wrong.
Scott Tolinski
We got those changes, and it it feels Like the ideal API for me, but also deeply, I have loved CSS nesting since I very first tried it. One of the very first Video series I did on YouTube was in Sass, and one of the first things I covered was nesting. And I gotta say, it feels fantastic to have it in in real CSS, Something that I've been dying to use. Yes. So first of all, nesting
Wes Bos
works is in the way that you simply write a selector.
How CSS nesting works
Wes Bos
You open up your curly brackets like you normally would in CSS.
Wes Bos
You apply all of your styles to that element as as you normally would. But when you want to nest something inside of that selector, then you simply write a selector inside of it.
Wes Bos
We'll talk about the ampersand in just a second because that was initially and you may have have seen it. A lot of people are like, oh, I remember seeing it and being like, oh, that's kind of annoying. That stuff has gone away, thankfully, and you can simply just nest Your regular selectors inside of it. And what that will do is it will say, All right, select these items, but it will essentially just extend the selector to the parent. So if you say, All right. I have a let's say we have an audio player. So you have dot player, right? And the player can have a border and a yellow background.
Wes Bos
And then inside of that, you want to maybe select like a button, right? Then you can just write button inside of it or button dot Pause or simply just .pause, and that will give you the equivalent of player space.
Wes Bos
Pause.
Wes Bos
And we won't do too much mouth coding in here, but I hope you get the idea of what the benefit of That type of thing is, is that you don't have to write longer selectors that prefix themselves Over and over again, you can simply just you can write some simpler selectors, and you can say, all right, well, when I'm inside the player, select all the buttons. You You don't have to give a class to every single one of those buttons. You can simply just select them.
Scott Tolinski
Yeah. And anybody who's been around pre SaaS will know that the pain of Having to write, a long even even like a a couple things nested chain was just you'd have parent, child, child, parent, Child, parent, and then looks like you're you're writing, like, duplicate, selectors CS over and over and over again, and this really allows you to minimize that duplicate selector In favor of code that not only is more terse. Right? You're not having to write the the same thing over and over again. But in my mind, it. If you are writing something that here's a parent and these things are contained within this parent, the code now kind of mimics the structure of the HTML in a way, even indentation wise, the same way that that HTML structure works. To me, that aspect of it is makes it that much easier for me To reason about my CSS code when I'm looking at it because I'm not looking at this here's this massive string of different selectors. I'm looking at as in here is this unit, And inside of this unit are different
When to use CSS nesting
Wes Bos
selectors that are all associated with the same group. Exactly. I think you can CS. And you should think about nesting selectors as a component, meaning that when you are styling something, You are grabbing on to the smallest possible piece of that. So my example of a player earlier probably actually is not a good example because I guess the player itself will have have some styles, but if you are using pieces of that player anywhere else On the website, then that should be its own component. So if you have a button that you are only using inside of the player, maybe that makes sense to style inside of But if you're like, I want this button style in the player, but we also want the button style on our forms.
Wes Bos
That's a good thing to yourself is like, no, that shouldn't be nested. That should be its own component that should have its own class on it, and I should be able to reuse it. So only nest things When you know that it is part of that component and will not ever be reused anywhere else on your application or your website. Yeah. Because otherwise,
Scott Tolinski
You've now really written a more specific selector than you may have intended on writing. And and that is some of people's drawbacks With CSS nesting is that people were just nesting everything inside of everything inside of everything. Next thing you know, You have these hyper specific selectors when you could have had something that was more generic and being able to be used in a reusable fashion, And you were almost, like, eliminating, like, a key feature of CSS, which is the ability to write a class that then you can assign to whatever because now you've Essentially written something that's an ID, something that's hyper focused downwards into 1 singular item. I find myself doing it a lot in React components or Svelte components where,
Avoid over-nesting selectors
Wes Bos
Alright. This is a card component, and that card component might have an h one And it might have a footer inside of that, and you don't have to like the footer of the card component isn't its own component. So you just style the footer and you put a border on the top and you make the Maybe make the font size a little bit smaller, you know. So that's the simple nesting.
Wes Bos
It works with every selector that you could Possibly imagine nested inside of it. But the next thing we'll talk about is the ampersand inside of CSS nesting. So it's important to understand what the ampersand does. The ampersand stands for the parent selector. So whenever you see an ampersand, you say, okay, if that were to be expanded, That will be referencing whatever the parent selector would be. So that is helpful because you can say like, all right, I want to style, all articles. So you select article, open up your curly brackets, and you say width 80%.
Ampersand parent selector
Wes Bos
Then if you want to make a wide a version of that because you pop a class of wide on it, you just say ampersand wide. And what that will do is it'll extend the current selector and say, all right, when there's an article with the class of wide, Give it a width of a 100%.
Scott Tolinski
So anytime you see the ampersand, it's the parent. And likewise, that parent works with So many of the pseudo selector types that we have used in the past, and I I love you have an example in your Twitter thread, about using it with the has, which, man, combining it with this with the has, pseudo selector is going to really change things for us where you'll be able to do Colon has image. So now if the article has an image, now all of a sudden, this article is something completely different.
Scott Tolinski
You could imagine in the past, we may have done that with, like, a a class. You would have had to have a special class on here that maybe is being even done with your templating language. Alright. In this particular one, it has an image, so therefore I'm gonna add a class here in my actual markup. But now we'll be able to say, Alright. This parent thing, if it it has the following styles oh, by the way, also, if it has an image, do these following styles. Or if, by the way, it has, You know, a and I don't mean has as the pseudo selector, a specific.
Scott Tolinski
Right? One of the things that we did in the in the syntax site is that we Styled specific links that were time stamps to have a completely different style. So you're able to use a attribute selector To look for a specific string inside of a time stamp, then you'll be able to say ampersand, the attribute selector, and then style those a specific way. Yeah. Any
Wes Bos
Link that has an h ref that star equals, I think it was pound t equals and that's a That's a timestamp link, then style those differently.
Wes Bos
And that's really cool because it takes the logic out of your Templating language like that. If we had to do that in our template, that would have been like if whatever.ref.matches equals whatever, then add the class of like timestamp link, which in some cases is okay. But If if you can get away with taking that logic out of your templating and just putting it on a CSS rule, often, that's a really good choice.
Scott Tolinski
Yeah. And it makes it super easy to read. It contains it all. It's keeping it all in one spot, especially using this ampersand, selector or the the parent Parent selector here. Yeah. So one of the
Wes Bos
earlier versions of the spec and actually the implementation In Safari and Chrome currently was that if you are nesting a I call it a bare selector. If you're nesting a selector that does not start with a symbol, Meaning like a dot for a class or a pound for an I. D.
Breakout selector with ampersand
Wes Bos
Then you had to previously put an ampersand in front of it so you couldn't just say, All right. I'm selecting a button and then inside of the button, any spans I'm going to like, I do this in my buttons on my website where a span has a price in it. So I want to make the price a little bit bigger than the text of the button.
Wes Bos
You would have to say ampersand button because If you're selecting a bare element selector, there was no way for them to just nest the selector right inside of it. It was a We had Adam Argyle tell us about this. He said it was like a parsing limitation where the CSS parser had no idea When it hit it, if this was a I don't know, if it was a property value or something like that. And they said they figured out that they just let the parser crash And they restarted it again. And somehow that was a way to tell that it was a nested bear selector inside of So the ampersand in front of like an element is no longer necessary In it's already implemented in Firefox and it's already in. You're going to be using PostCSS to transpile these for older browsers anyways.
Element selectors don't need ampersand
Wes Bos
So don't even learn this. You know, like you maybe need to know if you try to use this directly in the browser, which is a bit of a pain.
Wes Bos
But otherwise, you can, you can just not learn this and just use it as you would expect it to work.
Scott Tolinski
Yeah. You also had an example using, the ampersand as a breakout selector, and this is not something that I had considered.
Scott Tolinski
But the way you have this, written here is that you have a child class. And then inside of the child class, you have dot parent ampersand.
Scott Tolinski
So that essentially is read as dot parent dot child, meaning that you are using the outer selector it as the inner selector simply by using the ampersand, and that honestly breaks my brain a little bit. Me too. It doesn't It doesn't seem like something you'll want to do that often, but I'm shocked that you can't do it, honestly.
Wes Bos
It's very bizarre. So the ampersand stands for the parent selector, and you can interpolate that selector wherever you want. So what you can do is Sometimes if you're nested deeply and you want to like, let's say you have an H2 tag And you're styling your H2 tag and then you say, Okay, but when this H2 is inside of this very specific blog post, then make it a different color. You know, like sometimes you just have these one off styles and say, Okay, it's always this, except For this one situation because somebody from marketing asked me to make a special change, you know? And if that were the case, you'd have to go all the way back To the top and say, all right, well, when the article has that idea of post 40 2, then select the h two's inside of it. And then that CSS lives separately from the rest of your H two styling, you know, and that's kind of annoying, especially if you've got, like, variables that you need to scope and reference.
Wes Bos
So The ampersand will allow you to basically break out of the current nesting level, start fresh from the top, And then use the ampersand to reference the the parent selector, which is apparently you can do that in SAS. I had no idea that that was a SAS feature. Yeah. I didn't know that either.
Wes Bos
I just that it's one of those things. Like, reading it, it just breaks my brain. And probably listening to this, it breaks your brain. So it's probably not All that helpful, but it's good to know that, oh shoot, I'm nested too level too deep. Now I got to go to a fresh c s No level indentation and start again. If that's the problem, remember, Google West Boss CSS nesting breakout.
Wes Bos
You'll find it and and solve your problem.
Scott Tolinski
I also like that you can use this with the sibling selectors.
Sibling selectors with nesting
Scott Tolinski
So if you don't know the sibling selectors are, we have the little greater than sign, which is for a direct child, like the thing directly Inside of something, the plus sign, which is something directly next to, and the, tilde, which is A sibling that's on the same level of, but not necessarily directly next to it. A future sibling.
Scott Tolinski
A future sibling. Yeah. I've never heard of being called a future sibling. Is that something that that you call it for? Probably do that. Actually called. Okay. Honestly, I don't know the names of anything in web development.
Scott Tolinski
Yeah. Wait. I I wonder what that no. What it's actually called. Let's look it up. Hold on. We are professionals here. The general sibling selector. General sibling. Yeah. General sibling. I I was going to say when I say future sibling, it makes sense, but it didn't seem like exactly
Wes Bos
like what I had seen it being. General sibling, that doesn't make sense because You could have a sibling before the selected element, and the tilde is not going to select that. Yeah.
Scott Tolinski
Interesting.
Scott Tolinski
But you can use these all within nesting, and, it it can make for some handy stuff. You know, for instance, this Maybe has gone out the window a little bit with the advent of, gap the gap property inside of Flexbox, but used to used to have to do things like, Alright. I have all my list items, and I want every single one that's next to the current list item to have a margin left of 5 pixels to get them That equal spacing between them. So that way you're not putting it on the first one. They used to be a nice little handy technique. Now granted you don't have to do that anymore, but, still, I find myself using the next sibling a little bit more often than you you might expect.
Previous sibling selector
Wes Bos
You know, with, CSS has, you can now do a previous sibling selector, which is wild. So You say, like, I did the example of having table rows. So I have 3 table rows. I select the middle one And the one before it and the one after it, I want to blur out or style it in such a way that you're not you know, when you're reading a table, Yeah, you're not paying attention to it. It's hard to, like, horizontally move. So I was like, I'll blur it out or something like that so you can select.
Wes Bos
Basically what I was saying, as I say, c s t r has plus t r hover. And what that means is that when a table row has a Immediate next sibling that is being hovered, then apply some styles. And the beauty of has is that you can select it based on other things in the page. So here we're saying is that when something has a sibling in front of it that is being hovered, style me this way, Right? And we've always been able to style the next item, but now we can style the previous item. Yeah.
Scott Tolinski
Here's something that does not work that did work with SAS.
:has pseudo selector with nesting
Scott Tolinski
It. You cannot essentially append a class to the end of something using the ampersand. So something that people used to do in Sass, and I must confess this was never a technique that I personally enjoyed. But I did see this being used a lot it. Where you'd have, like, in BEM style syntax, you might do a class of block and then ampersand and then your underscore underscore element And then ampersand hyphen hyphen modifier nested so that way it would append the word element or the element's name to your block, or it would append the modifier to the element block. Right? It would actually concatenate the strings for you in Sass, But you cannot do that in the CSS version of nesting, which I gotta say because I did not use this technique, I'm fine with it. But it's something that, you know, those of you out there who may have used that technique in before should be aware of.
Wes Bos
I found it tricky, And this can be the same thing with nesting. It's tricky to find where in the CSS a specific style was authored Because you're concatenating strings, right? And SaaS, nesting still, when you're viewing the compiled output, you have source maps that will Ideally tell you where where this piece of style was. But if you're just trying to do a quick search on your codebase Command f. Yeah. You can't find it. Yeah. Exactly.
Wes Bos
It works with media queries. This is a beautiful thing is you can stick a media query inside of the thing that you want to style.
Nesting media queries
Wes Bos
And that is really nice because previously with media queries, you had to write your styles.
Wes Bos
And then if you wanted to write some styles Elsewhere for a media query, you'd had to go, again, not inside of that selector, but you have to say, alright, well, Let me top level write a media query and then write all of those selectors again and apply it. And the beauty of Sass is that you could stick a media query inside of anything. So you could say, alright, I have a container, and then you can put the media queries with that container. And all of the logic as to how does it work is just in one selector. And that, to me, that's really nice to have it all in 1 component, in 1 space.
Wes Bos
And you can nest them As deep as you possibly want, which you probably shouldn't do, but you can put them at any
Scott Tolinski
Level deep. Yeah. And it also works with container queries, which gosh, man.
Scott Tolinski
I don't know if you've been using container queries much, but I have.
Scott Tolinski
And especially on the syntax site, it's like anytime that I'm thinking about using a media query, I'm almost always reaching for a container query now. And it it feels as good as you would have hoped it would have when, you thought about it back in 2011 or something.
Scott Tolinski
It really nothing beats it. Container queries rule and the fact that you could just nest inside of them makes it really nice and easy to feel like it. It's all contained inside of 1 little wrapper, 1 little thing, and it it fits so well with the general thought Process behind CSS nesting that it feels like 2 peas in a pod for a feature set for me. Exactly. And you don't even have
Wes Bos
To name your container if you are asking. No, I still do anyways. Do you? I guess that makes sense to be Like maybe for dev tools or for BL to reference it outside, but if you don't name it and you reference container inside of a nested, it will just Look up
Nesting container queries
Scott Tolinski
the scope tree to its parent container and then apply those files to it. I'm the type of dude who writes return types in TypeScript. So, You know, if even though it's not necessary for some reason,
Wes Bos
it feels a little bit more explicit for me. Yeah. You're explicit. I I don't think I've written enough container queries to have too many strong opinions on it yet, so maybe we'll have to
Scott Tolinski
come back to that. Yeah. Do you know what I also been doing too? This is A side note, I've been naming all of my grid areas now. Anytime I have grid templates, grid columns, anything, I'm naming those grid columns. I'm naming those grid rows, and it is awesome, especially because you can have kind of, like, groups of names for things. So So you can have, like, a start and an end and a content and a content. And then I could tell, I wanna go from start to end or I wanna go from Content to content, and that will just fill up the content column or the side column or whatever. Check it out. I actually did it in the, the layout class in the new syntax site, and it is Chef's kiss. It's lovely.
Scott Tolinski
Yeah.
Naming grid areas for reusability
Wes Bos
What's really nice about that is you can redefine your grid areas Add a container or media query, and you don't have to rejig any of your layout because you simply said go into the sidebar.
Wes Bos
And then if you change how big or where the sidebar is, it will simply snap to you don't have to do it like I did Another tweet tip a couple of days ago where I laid out the differences between a sync, defer, script tag and module, And I built a little visualization with CSS Grid. And I said like, alright, this is it. This is downloading, this is rendering, this is execution.
Wes Bos
And every time I wanted to change how big rendering was, I had to go all all 3 of them and change the start and end. And I was like, damn it, I should have just named The grid areas,
Scott Tolinski
because then I can just change how big the grid area is and it will snap too. I don't have to worry about alright. Stop at 5, and then the next one start at 6. Yeah. And it it tracks with how you think about content in a grid. You don't think about this content goes in the 2nd column and spans 3 columns. You think, no. This thing goes in the in the content area. This goes in the sidebar area. You know? So we quickly have talked about in the past,
Wes Bos
how do you make this work on all the browsers? So it is just syntax, meaning that This is not a new feature CSS has. You can't use that until all of the browsers support it or you can't use it for like mission critical things That you need to work in every single browser. Why? Because it's the browser literally has to implement it. Yeah, there's probably JavaScript polyfills and whatnot, but That's probably not worth it.
Wes Bos
With nesting, it's just syntax, so meaning that you are still writing regular CSS And it can be transpiled compiled to CSS that is supported in all the browsers, so you do not need to sit and wait To use this type of thing, just like your Sass had been compiled, you can do this. And maybe that's another thing I want to talk about as well is people are saying like, Well, why not just use Sass? Like, what's the benefit of this type of thing? There was a lot of people that were I think I understand why people get angry because they're sort of exhausted that they just wrote their entire app in SaaS.
Browser support via transpiling
Wes Bos
And now there's this new thing like I don't care about that type of thing where it's 98% the same and I have to spend some time moving it on over.
Wes Bos
But the benefit to this over Sass and you can go back to episode 603, can vanilla CSS replace Sass yet? The benefit of that is you see you get live variables, you can do container query lookups, you get all of the scoping like this is.
Wes Bos
This is standardized JavaScript, or sorry, standardized CSS, and all of the tools, all of the libraries, everything that you're going to use is Standardized. So that's to me, that's the benefit of this type of thing. It's not that Sass is bad. It's that Sass is so good that we literally added it
Benefits over Sass
Scott Tolinski
To the language. It's the, the the actual example of j let's add jQuery to the browser. Yeah. But Exactly. This time with CSS. CS. I was actually thinking about that. I was like, I think we'll have a show on
Wes Bos
like things that were so good, jQuery, Express, Sass. Things that were so good, we added them to the browser. And sometimes people look back and they say, Ah, jQuery, what garbage that was. And it's like, No, that literally was the best thing ever. That's the reason why no one uses jQuery anymore is, yeah, because of, like, react documents.
Wes Bos
We got better selector. We added it to the browser. We don't need jQuery anymore because we standardize it. And now it doesn't have to be a jQuery plugin to make it work. Right? Yeah. But the dollar sign was pretty cool, though. Right? I mean, that was pretty cool. Right? That was. Bling. Js. That's I use that a lot on my own project.
Wes Bos
You get the dollar sign. Bling. Js is like a tiny little library that Adds dollar sign to query selector.
Wes Bos
It adds, .on to add event listener.
Wes Bos
Oh, my gosh. It adds some I think for each to a node list Or no, map rules.
Wes Bos
It adds map to a node list because a node list you can't map over unless you convert it from a node list to an array.
Wes Bos
And it's like it's like 5 or 6 lines of code. I've tweaked it a little bit to add a couple more things myself. But when I rewrote My checkout and everything from jQuery to vanilla JavaScript, I wrote a little wrapper so that I didn't have to Do the whole like the other. The other thing with jQuery is it fails silently, so you select an element and then you do that for each On the end or and if it comes back with nothing, then you have a syntax error. And then you always have to check if the thing is there Or if you want to add an event listener to something that's undefined, then that's a syntax error. So the nice thing about jQuery is that it just failed silent. If it's not there, I don't care. Don't I'm attaching that event listener. Well, that's sick. Alright. Well, this episode's getting a little tasty, so let's put a, a stopper here Oh, yeah. For this one. I got one more thing to add.
Scott Tolinski
Lightning CSS. Oh, yeah.
Lightning CSS alternative
Wes Bos
Lightning CSS is a post CSS alternative.
Wes Bos
It's written by Devin, who also created Parcel, and I believe that we will start to see a lot of people moving to Lightning CSS in the future.
Wes Bos
I know Tailwind itself is moving to Lightning CSS from PostCSS, and they have Experimentals support for CSS nesting, it doesn't do the you still have to do the ampersand thing we talked about earlier.
Wes Bos
But I I bet that will maybe by the time we this episode comes out, it will be fixed. Word.
Scott Tolinski
Okay. Well, that is it.
Scott Tolinski
Well, thank you so much for joining us today. CSS nesting, gotta gotta love that we have it.
Scott Tolinski
CSS is just one of those it's So much momentum behind improvements to CSS right now. And it feels like the next thing on the docket is gonna be has, which is In Firefox underneath a flag right now and everywhere else. So, hey, maybe we get to do a full episode on HAS tips coming up soon here once HAS officially drops into every browser. Thanks so much for joining us in this lovely hasty treat.
Scott Tolinski
Head on over to syntax.fm for a full archive of all of our shows.
Scott Tolinski
And don't forget to subscribe in your podcast player Or drop a review if you like this show.