November 27th, 2023 × #CSS#webdev#frontend
Why You Should Be Using CSS @Layers
Wes and Scott discuss CSS Layers - a new way to control cascading and specificity by defining layers of CSS.
- Discussing CSS Layers
- What CSS Layers are
- Browser Support for CSS Layers
- Purpose and usage of CSS Layers
- Layers solve specificity issues
- Redesigning sites with legacy code
- Handling third party CSS overrides
- Defining layer order ahead of time
- Authoring order matters without defined layers
- Overriding legacy CSS with layers
- Non-layered CSS precedence
- Inline styles precedence over layers
- Non-layered CSS overrides layers
- Using @import to wrap legacy CSS in layers
- Nesting layers for finer control
- Example layer usage
- More layers provide more benefits
- Tailwind uses layers under the hood
- Adam Argyle's nested layer usage
- Una Kravitz's simple layer usage
Transcript
Announcer
Monday. Monday. Monday.
Announcer
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 ed treats coming in hot. Here is Wes Barracuda Boss and Scott
Scott Tolinski
key. Welcome to Syntax on this Monday hasty treat. We're gonna be putting some of your into different layers by talking about Lair in CSS.
Discussing CSS Layers
Scott Tolinski
What it is, why it's important, why you should be using it, And who else is actually using this thing considering the support for it is excellent.
Wes Bos
Not too much. A little sick, so you get to hear my boomy voice today, Excited to talk about at layer support because when we use this in the new syntax website, I was like, Oh, this makes so much sense to me.
Wes Bos
And I was like, Scott, you got to throw a hasty on here about just how this works because it's relatively simple. It will be a short episode, a. But it will cause all of the specificity problems that you have to go away.
Scott Tolinski
I love it. Yeah. Definitely. And there is some nuance here. By the way, I almost called you west base layer boss, which I think I should have done. That would have been Oh. That would have been pretty cool if Base layer. Well, You know what I was thinking about the other day?
Wes Bos
I was looking through a bunch of new APIs, and there's this one called BigInt.
Wes Bos
I was like, BigInt would be a Sick, like, nickname. You know? Yeah.
Scott Tolinski
Wes Bighin, boss. That's good. Bighin? Yeah. It works particularly well with your name. Well, if you would have messed up the intro to the episode by not calling Wes, base layer boss, you might mess up your code too. And if you mess up your code, you You gotta have an error and exception handling service to track that because let let let me tell you. We just launched a new website, and we use the tools at [email protected] To track all of our errors and accept all of our errors and exceptions and find out what was going wrong at any given point. Not only that, There's a ton of amazing new performance and profiling tools, web vitals, and stuff that we've been able to track and improve our performance over time. A And I gotta say, we're we're not just passing the eye test. We're passing the the century performance test now too. So check it out at century.i0.
Scott Tolinski
S Use the coupon code tasty treat to get 2 months for free. Alright. CSS at layer. And we we'll say at layer, but we'll refer to it as layer There were layers throughout this episode.
What CSS Layers are
Scott Tolinski
It the reason why is that to use this thing, it is the at sign and then the word layer.
Scott Tolinski
S. So, what does support look like before we even get into this? Because sometimes with new CSS topics, your brain shuts off until you know where you can use it. Well, this has been supported in Chrome since February of 2002.
Scott Tolinski
This has been in 2002? 2002.
Scott Tolinski
Like, 20 years? No. I'm sorry. 2022.
Scott Tolinski
What am I talking about? Holy smokes. Oh, yeah.
Scott Tolinski
No. 2022.
Scott Tolinski
Yeah. What? Sorry, Al.
Scott Tolinski
I I went back in time there. I stepped into a time machine.
Scott Tolinski
Next one is Safari. It was supported in March of 2022 as well, and it's been in Firefox since February of 2022.
Scott Tolinski
So you can use this thing. It has been there for a while. There's there's nothing holding you back here. So what is it? Well, basically
Wes Bos
Sorry. One more thing is there's a post CSS plug in for it as well. So even if you are supporting Sure. Internet Explorer 6 or something like that, It's not an issue, and it's part of, post CSS, ESV, so you're probably already using that. So you can just start using them and not have to worry about, well, it work in all the browsers.
Browser Support for CSS Layers
Wes Bos
It's compiled away at the end of the day.
Scott Tolinski
It. It is very, very usable.
Purpose and usage of CSS Layers
Scott Tolinski
We're we're not having to worry too much about fallbacks or progressive enhancement here on your end. S. So what is it? Why would you use it? What's the purpose of it? Well, it essentially allows you to encapsulate your CSS into different layers And then control the cascade order of those layers.
Scott Tolinski
So for instance, you have, Let's say your your reset CSS or something like that, which you'd think of that goes on first, and then everything else goes on top of that.
Scott Tolinski
Well, you can throw your reset CSS into a reset layer.
Scott Tolinski
Then you can throw your other CSS into another layer. And then without having to worry about specificity order, the base CSS or the reset CSS will always be below s The CSS on top.
Scott Tolinski
And what's so cool about this API is it basically takes s The authoring position of your CSS out of the equation if you use it correctly.
Layers solve specificity issues
Scott Tolinski
So many times, s. We write our CSS, and we have to be cognizant about where it's written so that way Mhmm. When it's applied, It applies in the correct order. That way we're not breaking any sort of weird rules. And then what happens, right, if we do break those rules? We end up Having to double, triple down on selector specificity, so, therefore, that makes it harder and harder to do overrides, or We'd add bad things like important to do an override.
Scott Tolinski
Right? There's a lot of different code smells that can come from this. S. So it essentially takes where you're authoring your CSS out of the equation, and you can now just put it in buckets And then control the order in which those buckets apply. Yeah. I I think that's really important because
Wes Bos
where we author and how we author our CSS is is constantly changing. Right? And you might wanna be able to throw a bit of CSS with your component. You might wanna do it, in line with utility classes. You might want to have a 1000000 different CSS files and having to sweat like 10 years ago, we had to make sure that our JavaScript was loaded in order. Right? 1st, you load jQuery, then you load your plug ins, then you load your custom, JavaScript in that order. And if one of those things is missing along the way, then things get broken. And our CSS is kind of still like that where CSM. You you just kind of you still compile it all into 1. But with this, it's nice to be able to just say, alright, I'm gonna throw in a utility class, And I'm going to add on some utilities. So I'm just going to wrap that in an at utility.
Redesigning sites with legacy code
Wes Bos
And then when your CSS is Harsed by the browser or when your CSS is compiled by a build tool, it will know How to group them together and how to apply, the specificity to those selectors, you don't have to sweat about it. So this is such a awesome thing.
Scott Tolinski
Yes. It's it's incredibly handy. And here's another use case in in, s. So third party CSS, how many times have you dropped some third party CSS into your application and It's overwritten something that you didn't wanted to override.
Handling third party CSS overrides
Scott Tolinski
Toss that stuff in a layer, then control the orders of the layers. Now you don't have to worry about it. So how do we write this stuff? Well, there's a couple of ways to get started. 1, you can define all of your layers a. Ahead of time, and you can define their order. Now this is how I think most people should be doing this because s This takes a lot of the guesswork out of it. If at the very top of your very first CSS file, you do at layer and then you write the names n. Of your layers in the order in which they'll be applied with commas. So for instance, you could do a 1st is reset, comma, base, comma, components.
Scott Tolinski
That means your base or your reset layer is the very bottom. Then on top of that, it gets applied base, and then on top of that, it gets applied components.
Defining layer order ahead of time
Scott Tolinski
That way, when you're authoring your components CSS, as long as you are Wrapping that CS in the components layer when you use it, it will then always be applied on top.
Scott Tolinski
Now this bit of things where you write this initial line is actually not required.
Scott Tolinski
If you just define your layers and use them as you use them, the order in which you 1st use them then becomes the order in which they're applied, which, feels like you're getting back to the whole point of, like, alright, the order of
Wes Bos
Right? But that's how it works. So 1 question I have, and I think this is a kind of a cool use case, is, if you are redesigning a website and you can't necessarily scrap, like, 8 months worth of code, you could Wrap your existing legacy code in a legacy layer and then make a 2nd layer for your new redesign and sort of Whatever crazy selectors are in that old legacy code do not matter For the next one. So if you have, like, an body space H one with an ID of something, And then and later in your new CSS, you simply just have, like, something with a class of heading.
Authoring order matters without defined layers
Wes Bos
Even though that selector is so much Less specific, it will still override it. Right? Yes.
Overriding legacy CSS with layers
Scott Tolinski
Yeah. Totally. So that's great for, these types of situations, unless, of course, you're dealing with important, which is still going to be the bane of your existence here. So, Maybe in that case, you'd want to find and replace and remove all importance.
Scott Tolinski
Because let's say you do have a legacy layer and there's an import let's say you have a legacy layer. There's an h one. It has a color of blue. That color of blue is at important. Right? And then you have a layer on top with a color of red with no important. S That important will stake to still take precedence over your layer, so be be careful about it. CSS layers will save you from Literally everything but important. Which is that's good. I wish it saved you from important, but that's good.
Scott Tolinski
So okay. So the layer in which they're defined really matters. Right? You can define it ahead of time or you don't have to, although it's probably the best practice.
Non-layered CSS precedence
Scott Tolinski
How do you actually write your CSS in layers? You do at layer, the layer name, brackets, and then nest your CSS inside of that.
Scott Tolinski
S. Now if you're importing a CSS using a CSS import, you can actually import as well with at import s The the CSS file and then apply the layer directly there with a layer function where you do layer, parentheses, the layer name, Then you can import a file directly in as a layer. I love it. And so pop quiz. If you have
Wes Bos
a layer, and you have an inline style.
Wes Bos
Which one wins? Inline style, right? Bam. Yes, you're right. So inline style still overrides layer, which makes sense because the whole order of specificity is Right. 1st, it does CSS that's been imported. Then it does CSS in CSS tags in the document, and then it does CSS in line on an element.
Scott Tolinski
Yes. And so And also to go along with that is, does it override non layered CSS? S. Pop quiz, Wes.
Inline styles precedence over layers
Scott Tolinski
Does it override non layered CSS? So if you have a Yeah. If you have, an h one outside of a layer authored as red, then you have an h one below that inside of a layer authored as blue. What color is that h one? I'm gonna say The non layered CSS
Wes Bos
will always take precedence.
Scott Tolinski
And it does.
Non-layered CSS overrides layers
Scott Tolinski
So if you are Starting to write your CSS and you notice you put something in a layer and it's not applying, well, double check s. That there isn't some CSS outside of a layer that isn't sitting on top of it. So a good strategy is to start Layering if you're, like if your CSS is not layered, it's probably hard to just start it out of the blue. But Yeah. If you wanna start your CSS because you think it would be cool or a nice thing to try. Start with the stuff that's the should be the base first. Right? Because the stuff that sits on top will always sit on top, And you don't wanna put your component CSS in the layer and then have the base CSS overriding that. So, again, non layered CSS. CSS always applies last, and that that makes sense too, especially with the inline CSS bit that you talked about. I think your little trick of using the at import
Wes Bos
and applying a layer as you import it is probably the fix If you have some legacy CSS that isn't in layers because you can sort of just wrap the entire thing, and then either the browser or Your bundle bundler tool will take care of that that layering for you. Yeah. How do you feel about import in CSS
Using @import to wrap legacy CSS in layers
Scott Tolinski
using So, like non bundlers.
Wes Bos
So usually, import in CSS, it's the same idea as, ECMAScript modules is that it can make waterfall requests. Right. So your HTML page loads.
Wes Bos
That fires off a link tag.
Wes Bos
That link tag will fetch your CSS and it will parse that CSS, and then it realizes, oh, shoot, There's an import in the CSS. I have to go get another one. Right. So now your 3 requests, plus whoever much parse time was needed for that CSS Away from your CSS being applied. So that can cause like, flash of unstyled content that can make your website Look. Look. Feel like it's loading slower because the c s the styles are applied after the fact. So, generally, we don't I don't use imports shipped directly to the browser. There was same thing with ESM modules that have requires. There was this whole idea that The browser would be able to push, which modules are needed. Because if you have, like, if you have an import that imports something else, that imports something else.
Wes Bos
Imagine you have 8 imports deep for 8 different files.
Wes Bos
HTTPtwo was supposed to allow you to load I hope those files at once. Right.
Wes Bos
But the browser has no way of knowing what files it needs unless you were to explicitly put A some like preconnect link tag in the head where it says, all right, as soon as you load, start fetching these resources.
Wes Bos
So it's kind of a bummer. There was a proposal for, like, server push, which, like, the server would understand what it needs, And the server would tell the browser, hey. You're gonna need these assets. I just I just parsed the whole tree, but,
Scott Tolinski
apparently, that was scrapped. Yeah. I know it's a it's like one of those APIs that would be really great if you could actually use it s Normally, you just use it and not have to think about it. But, you know, a lot of CSS, whether you're using, you know, preprocessors or postprocessors or whatever, They all support some sort of a compile time
Wes Bos
at import anyway, so that's typically what I end up doing. You know what? Is that a show I wanna do is We should have Brian LaRue on because he is mister.
Scott Tolinski
Yeah, mister. No compile.
Wes Bos
Ship the JavaScript you wrote to the browser, which is wild that apparently he doesn't use any build tools or anything like that. So I'd love n. To get his opinion on that. Well, well, well, if it isn't mister no compile,
Scott Tolinski
let's talk about nesting.
Scott Tolinski
Did you know that you can nest layers too? So nesting layers can be used for greater control over the naming and even, Like fine tune control over your layers. So beyond just having, like, a legacy layer, you could have a legacy a layer and inside of that, a legacy layout layer. And those can be defined just by straight up nesting them. So you could say at layer, legacy a Brackets and then inside of that atlayerlayout.
Nesting layers for finer control
Scott Tolinski
Right? Or you could do it as atlayerlegacydot layout, and that that in the same way would work in the exact same way as the actual nesting of it to give you that more fine brain control. What's What's the point of nesting
Wes Bos
nesting layers?
Scott Tolinski
What is it just so you can group your your code together? Yeah. Let's say you had a base layout, And then you had base colors, and then you had base typography.
Scott Tolinski
It's basically just like I think it's a little overboard, But when we look at Oh, I see. Adam Argyle's in a little bit, you'll see how he uses it, and it might click a little bit more, Because that's something that he uses quite a bit of. So maybe even like themes. Right? You could have, like, based
Wes Bos
layout, based typography, And then you might have a whole another set of theme layout and theme typography Because you want the theme typography to override the base dot typography.
Scott Tolinski
Does that make sense? Yeah. Okay. I could see that. Yeah. It it's all just about the name of the game here is control and how much control do you need or want. And and sometimes it can feel like, hey. You don't need that much.
Scott Tolinski
N. That's too much control. Maybe you end up getting into layer hell or something. But Yeah. Hey. That's just the way it is. A. The layers that we ended up using on the new syntax site is at layer reset, then base, then utilities,
Example layer usage
Wes Bos
then layout, then theme. It makes sense because if we are in a component and we want to add a little bit of CSS to that component.
Wes Bos
It it might not make sense just to throw, and sometimes, yeah, it just scopes to the component and whatnot. But If you need to be control the order of which it is being loaded, we can in that component, you can just say layout or at utilities, and it will stick it in that layer for you.
Wes Bos
It's also available in Tailwind. So Tailwind takes care of a lot of the specificity issues for you, but There is possible issues that can still pop up with this type of thing.
Wes Bos
So with Tailwind, there are 3 layers. You have your base, you have your components, And you have your utilities. So your base is like your general fonts and things like that. Your components are buttons and whatnot. And then your utilities are filters and transitions and and things like that. So if you are especially if you're using, like, apply or you're you are creating your own utility classes that need to be added in your CSS file.
Wes Bos
You put them either in your base components or utilities layer. And then when your tailwind is generated. It will stick those selectors into the layer that is needed. So you're not having any Specificity issues that may override each other. You might say, like, I made this special button class, and it's not applying because Something else. Or I made my own class, and now I want to override the background color on that one with a regular tailwind class, and They're not overriding each other as I expected, so you always stick them into a layer so that you never run into those issues. Right.
Scott Tolinski
Yeah. So layers are one of those things that they're they're helpful the more you use them. Like, if you put your CSS into the layers, it makes more sense.
More layers provide more benefits
Scott Tolinski
One thing that we did is we went across a lot of websites and tried to find, like, even newer websites because, you know, even though this did come out Sometime last year, early last year.
Scott Tolinski
You know what? Not a ton of people are using Lair for some reason. In fact, People who've just recently done a redesign, we've gone to their website and not seen Lair.
Scott Tolinski
We ended up using Project Wallace, which is a really cool site. So project wallace.com will have some links in the show notes, and we analyzed a few different websites to see what their layers were. Wes, do you wanna take The first one? Yeah. I was just thinking about this. So before the show, we were trying to find websites that actually use Atlayer,
Wes Bos
and we're like, man, No. A lot of people are using it, and then I realized that, like, everybody who's using Tailwind is using is using layers. You know? So The reason why it's not pop but they're not using the native language. The reason why it's not popping up is because most people are probably still compiling it away Because post CSS detects, oh, you're supporting.
Tailwind uses layers under the hood
Wes Bos
If you're supporting a browser that doesn't have it, We're still compiling it away because there's 3 a half 1000000 people weekly installing the post CSS plug in. So you're not going to see them in the wild, but you probably are seeing them authored quite often. So the one that I did find was Netlify.
Wes Bos
Netlify.com has a bunch of layers.
Wes Bos
They have blocks, Block layer, utilities layer, composition layer, variables, legacy, and base. So variables is kind of interesting as well because you can often run into issues with variables being incorrectly scoped Especially it's so hard to debug variable scope, right? Like if you redefine something at a selector level.
Wes Bos
So it's kind of cool that they have a whole layer for their variables. Maybe that's something we should have done as well. They have a legacy legacy layer and a base layer. So it looks like their base layer includes like a CSS reset.
Wes Bos
Legacy includes older codes that they have. Variables is things like gradients and colors that need to be applied on different parts of the website.
Wes Bos
Composition looks like, like layout based stuff. There's a lot of grid, a lot of text alignment stuff in there. And then the utilities Has things like visually hidden, gradient text, resize block, resize inline, scroll block, sticky, Height screen. So just a bunch of handy utility classes that can throw on something to to make it do what they want. We looked at Adam Argyle's site because Adam, a
Scott Tolinski
is always up on the latest and greatest. So we have his as well, which is nerdy.dev, and he uses 14 different unique unique layers, but most of them are nested, Wes. There's only a couple of them only one of them that's not a nested layer, which is at overrides or overrides, not at overrides.
Adam Argyle's nested layer usage
Scott Tolinski
Overrides, as you can imagine, applies on top and just overrides things, but he has a number of different components based layers. So it's like he's taking Each individual like, the Toast component is in a components dot toast layer, right, or the markdown component. So he's scoping Each component to a layer, which is the kind of thing that, like, a a Svelte lit component scoping does for us. But, again, Like, that's that's a a neat strategy.
Scott Tolinski
One thing he he did is his variables or at least his base variables in a layer named base dot props, and then that's set below everything. And then there's like a base dot theme where it defines a bunch of, like, theme layer variables as well. But I I thought it was interesting. If you wanna see a interesting use case of nested,
Wes Bos
properties. This is a good one. The overrides is is looks similar to Netlify's variables layer Where it has just inside of it are a bunch of media queries for light and dark mode and supporting different colors And when they support different colors and he's changing it to the new P3 color. So if you pull it up on a It's going to look much better than that type of thing. So I guess instead of using fallback colors, He's just saying if it supports high dynamic range or,
Scott Tolinski
at a specific media query breakpoint, then change these variables. Yeah. A I I liked Una's a lot. We have Una Kravitz's website up here. You know, the reason I like hers a lot, if you take a look at hers, her website is una a. U n a dot I m.
Scott Tolinski
Hers is nice and simple.
Una Kravitz's simple layer usage
Scott Tolinski
We got resets, then base, then utils, then blog. I gotta That's, like, right up my alley there,
Wes Bos
and that makes perfect sense for the type of order of this type of application. Awesome. So that is CSS Layers. Hopefully you enjoyed that and you learned a thing or two. Try throw them in your next website as they certainly will help m. Down the road as your your website starts to grow in complexity.
Scott Tolinski
Yeah. And, honestly, I think it's a great technique to learn. It's the type of thing that As a hiring manager, I'm looking to see if somebody has, like, full control and knowledge of their domain.
Scott Tolinski
Atlayer is one of those ones, like I said, great support, great functionality, great usability. So, yeah, check it out. Awesome. Peace. Peace.
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.