February 12th, 2024 × #css#frontend#webdev
CSS Native @scope
This episode covers the new native CSS scoping feature using the @scope rule, how it works, what problems it solves, and browser support status.
- Introduction to native CSS scoping
- Scoping eliminates need for naming conventions like BEM
- Scoping fixes main CSS problems, used by many popular tools
- How native scoping works syntactically with @scope rule
- Scoping works great for component based development
- Can scope styles without specifying selector
- Enables Svelte-like scoping without build step
- Current browser support status
Transcript
Scott Tolinski
Welcome to Syntax on this Monday Hasty Treat.
Scott Tolinski
We are going to dial in our focus, and scope our thoughts into the native CSS scoping API at Scott. We're gonna be talking all about what you need to know about this thing, how it works, and some really, really, really cool things that it allows you to accomplish. I'm I'm actually after, you know, looking over the notes for this episode, I'm distraught that I'm not using this all over right now. So, we're gonna be talking all about Scott. And with me JS always is Wes Bos. What's up, Wes?
Wes Bos
Not too much. I'm excited to talk about scope here. We it's Gonna be a fairly quick episode. There's not really a whole lot to it, but it's certainly something that the audit should know about as it's coming down the pipe.
Introduction to native CSS scoping
Scott Tolinski
Yeah. I'm I'm Scott Tolinski, by the way. I did not say that. I'm also coming down the pipe. I am getting my day ready here, But you know what's also coming down the pipe, Wes, with me? What? As well as scope? Century. Century's new features. Errors. Errors.
Scott Tolinski
Lots of them. In fact, that's one of the things that we were the most curious about when we talked to the folks at Century Wes how do you deal so much, So many things come come through those tubes.
Scott Tolinski
This this podcast is presented by Sanity, and Sentry is a wonderful way to track how your application, your website, your stuff is working at any given time, collect the bugs, solve those bugs, fix your problems, move on. So let's move on and talk about scope.
Scott Tolinski
Wes, You wanna hit us with the whys?
Wes Bos
Yes. So scoping your CSS is is nothing new. We've had many ways to scope our our CSS, both from, like, naming conventions all the way over to, like, lots of things like the Svelte SvelteKit has scoping built in.
Wes Bos
However, like all good things, they eventually get added to the language. And they're they've been trying to add scoping to the language firm For a long time, there was a Scott attribute on the style tag for a while, and that got scrapped. And it looks like finally, we are going with the at scope rule. So the reason the reason why I think this is kind of interesting is because, like, scoping is something all of us need to do. We've all run into applications where you have lots and lots of global CSS and that CSS applies to absolutely everything on the page. And It's kind of nice in some cases where it cascades all the way down, but you often end up in places where you can't just take components out of your website, and have them sort of live on their own, and have the CSS sort of be coupled with them. And scoping CSS allows us to to do that. You're not going to have styles that leak outside of of where they're supposed to go. CSS scoping, there's no need for complex naming conventions.
Scoping eliminates need for naming conventions like BEM
Wes Bos
So BEM was a very popular one where you would you would name thing as a block element modifier. You'd have these really long class names on it, And it was a great way to sort of keep your CSS modular and, be able to scope it to what it exists. But you don't you don't need any of that stuff with it. You don't need to add a 1000000 classes to everything.
Wes Bos
You can simply just write very simple CSS selectors, often element selectors like p Or h two to actually target the the element that you want.
Scott Tolinski
Yeah. And I have a little bit of a hot take here.
Scott Tolinski
Give it to me. Yeah. This is my hot take around this subject.
Scoping fixes main CSS problems, used by many popular tools
Scott Tolinski
Many of the tools that people like and, are just, you know, in love with in their process for working in CSS, are only liked as much as they Yarn, because they make scoping easy. I think scoping in CSS is the one problem that people have a hard time within CSS, and lots of tools, the main problem that they're solving is scoping. Whether that's CSS and JS, or even like Tailwind. Right? Co locating your styles in places. Those Yarn, at the end of the day, might not seem like scoping issues, but they're almost all scoping issues.
Scott Tolinski
And Scott me, At Scott is my most requested CSS feature right Node. I gotta have this thing for a number of reasons. And actually, this is, I I found this while looking.
Scott Tolinski
There was an old API that you have to use the, Wayback Machine to look at called scoped and attribute on CSS. So it was Yeah. That's what I was referencing earlier. Oh, you referenced it earlier. I'm sorry. I missed that part.
Scott Tolinski
So this was something that had been considered before.
Scott Tolinski
And I think at one point, Scoping your CSS tightly was seen as maybe, like, not the right way to do it. But as we've evolved into these component based flows, where your components kind of own their styles. Yeah. Scoping just makes more and more sense.
Wes Bos
I agree. Especially like you see like, sometimes you open up a storybook, which is like a UI for viewing your components and building your components in isolation.
Wes Bos
And it's just like, damn, that's so nice that these This this component looks exactly the same if you put it in a blank HTML page JS if you were to put it in your application.
Wes Bos
Because I feel like that's where, like, websites start to rot, where you you take a component from like, I have this on some of my course websites. It's like I'll take a button out of 1 of the sites and put it into another one, and it'll look slightly different. Like, oh, yeah. Shoot. Like, it didn't inherit the style because it's not on this page, and That's how, like, style rot starts to happen. So I'm a big fan of that. So how does it work? Well, we're going to throw some screenshots up on the video podcast as well. If you're on Spotify, you should be able to just switch to the video and back to audio.
Wes Bos
If you're driving, please don't do that. But I'll describe it as well. The way that it works is you have an at Scott, so no different than at media.
How native scoping works syntactically with @scope rule
Wes Bos
You open up a scope block with at scope and then you give it a, a selector.
Wes Bos
You don't have to give it a selector. I'll talk about that in just a second. But if you want to say, all right, If you have a card, I want to say at scope, you have to have the parentheses, in my experience, Yarn. And what that does is it opens up a scoping block for the elements that match that selector.
Wes Bos
Then inside of that scoping block, any CSS you can imagine, With the exception of one thing, I'll talk about that in a second. So any CSS you dump inside of that scope block will only be applied to the element that is Vercel, in that specific scope. And you don't have to. This is a little bit you might be saying, oh, how is that different than nesting? It's a little bit different than nesting in that. You don't you aren't making these crazy long complex selectors. With nesting, you have Scott card space p, And with CSS scope, you simply just have paragraph selector and that will apply to any paragraphs that are inside of my card scope.
Wes Bos
And I think that's pretty neat that you just I find the same thing was felt as well. It's like, oh, it's beautiful. You don't have to, like, add classes to everything.
Wes Bos
You just select the you you can add classes to stuff. There's nothing wrong with adding classes to things. But if you just want us to you saw a style, all the paragraphs or you want to style the 1 unordered list In that component, you can. Yeah. And
Scoping works great for component based development
Scott Tolinski
man, if you're working in a component based workflow, this will all feel like a breath of fresh air. The same way that it did the 1st time you did styles in Svelte, because that is such a nice way to be. It's a nice way to say, in this thing that I'm working in right now, I would like to apply the styles to this and only this.
Scott Tolinski
And Yeah. There's something so great about that. So
Wes Bos
one cool thing I've Ever since I read this, I'm like, damn, I love that.
Can scope styles without specifying selector
Wes Bos
And it's the idea of not having to specify a selector for your scope.
Wes Bos
And the idea is, is that you you have a component.
Wes Bos
And when I say a component, you have a element like a div.
Wes Bos
And if you put a style tag inside of that div with a scope block into it. The browser will figure out, Oh, they didn't tell me what the name of the scope was, so I'm just going to scope it to whatever the parent of the style tag JS. So you can just very similar to in Svelte, how you have A component and you have a style tag next to it in the same file, you could just say, All right, add scope And you can apply the CSS and it will only be applied to the elements inside of the parent card. And I think that's so cool because you can make these like super portable little pieces of HTML that have the CSS Assigned to it without having to be like, alright, we'll make sure you add this specific class. You don't need any classes. You don't need anything like that. Yeah. This to me is the space that I'm most interested in. I'm working on some stuff right now just using straight HTML
Enables Svelte-like scoping without build step
Scott Tolinski
template tags.
Scott Tolinski
And how I mean, not actual template tags, but just template tag literals of HTML.
Scott Tolinski
And how awesome would it be to just throw a style in there? That is almost you get the power of a Svelte style Yeah.
Scott Tolinski
Component Wes you have that that same exact interaction without the compilation step.
Wes Bos
There's no build step. I didn't even say that. That's a thank you, Scott. That is awesome.
Scott Tolinski
Yeah. Yeah. I'm jazzed up right now. It's so cool. And,
Wes Bos
sort of while I'm on that thought of Having Scott CSS inside of an element, pseudo inline hover styles? Yes. Yes. One thing Yes. One reason why people absolutely love Tailwind and don't like inline styles is because inline styles like style equals quotes.
Wes Bos
They're limited in that There's a whole chunk of CSS that you can't do in an inline style. You can't do hover styles. You can't do media queries. You can't do container queries. Has? You can't.
Wes Bos
Yeah, you can't do has you can't do parent child selectors, right? You can't do any of that. And Tailwind makes all of that possible, which is amazing. And I'm not saying this is going to replace tailwind. It's probably not because the tailwinds to text is much nicer. But look at this example where you can you have a button and you want to add a hover hover background to that button. How do you do that in CSS? Well, you you make a class, You put a style tag below it, and you give it an you give it a class. You say, alright, when this class is hovered. So now you can just stick a style tag in the freaking button and say at Scott. And then you can select the button itself with the colon scope selector.
Wes Bos
So colon Scott, colon, hover Background red. And it's just like you're and you can do that with media queries, you can do it with container queries, you can do it with any Vercel, and it would just be Scott to that specific element.
Scott Tolinski
Yeah. I I I'm I'm resisting the urge to make a colon scoping joke.
Scott Tolinski
Are you above the age of 40? Get your colon scoped. Colon scoped. Yeah. I Wes trying really hard not to do that, but I had to do it.
Wes Bos
Alright.
Wes Bos
Now you might be saying, okay, Wes, that's dumb. All of that stuff, I don't have those problems that that solves. Yeah. Here's here's a really cool thing.
Wes Bos
Sanity scope. And we talked about this with GitHub Bramas Wes when he had him on the podcast, his CSS donut scope will allow you to specify where the scope starts. Of course, a class can can say, alright, apply these styles to this class and any images within that class. You want to do something. The problem becomes with the sea of cascade of CSS. The C and CSS stands for cascading, meaning that any CSS you apply at the parent will automatically scope all the way down. And Node problem we have in the syntax website is variables. Do this very you set a variable at a very high level. There's no way to stop that variable from going all the way down unless you were to reinitialize it. Right? So if you have a card inside of a card or you have a dark sidebar with a light mode card inside of that.
Wes Bos
The problem is that when you redefine a variable at one level, the variables all the way down the DOM tree. You get overwritten with Sanity scope. It's going to allow us to stop the cascade at a specific spot. So you say at Scott card to Scott call out. So basically you're saying this is where it starts, the end of the Sanity, and this is where it ends, the whole of the donut.
Wes Bos
And I was trying to make like a Wes I was doing demos for this, I called it Timbit Scott.
Scott Tolinski
But It's like the opposite, isn't it? Aren't Tibbits the center? Timbit scope would be the inside.
Scott Tolinski
So the Timbit scope.
Wes Bos
Inverted Timbit scope.
Wes Bos
I don't know if everyone would get that. As a Canadian podcast Yeah. We need to tell everybody that in what do you call them in the states? Doughnut holes?
Scott Tolinski
Donut holes. Yes. We call them donut holes from Dunkin', I believe. I I did grow up with Tim Hortons around the block, so I Okay. You know what a Timbit is. I'm familiar.
Wes Bos
Yeah. So donut scope is is pretty nifty, and I could I can see ourselves using this in components, being, like, scope it from This card to Yes. And then like like a child. Right? So you might want to Or or to the next scope. Like, I I could also imagine, like, every single time you have a component, you give it, like, a a class of component. You're like, alright, Go from here until you hit the next component, and then stop, and then that component will have its own scope. Don't don't apply it to any children. The only, like, one weird thing is that if you have a background and you have a nested component, it's it's not gonna, like, punch out the background, so you'd have to reset the background. Mhmm. It would be nice if you had, in addition to the colon scope, if you had, like, a colon end scope.
Scott Tolinski
Because if you were saying so you could say that, oh, no. Wait.
Wes Bos
Never mind. That doesn't track. Ignore one. Wes. Because you you can do it with all the and all of this plays nicely with CSS, Like the ampersands? So the ampersand will give you the the parent selector, and you can use has, and all of the new CSS stuff, In addition, works well with this. So you have really fine grain control over the elements that you are selecting.
Wes Bos
Last thing, browser support. It's in Chrome. Just hit Safari technical preview.
Current browser support status
Wes Bos
So it will we don't know if they're just, like, testing it out or whatnot and Trying to find things. There's Node limitation we did find. Adam Adam Wathan of Tailwind was was actually investigating this because I'm sure he's got lots of scoping issues that Sanity fixed by this.
Wes Bos
Keyframes must be global.
Wes Bos
So If you want to if you want to generate a specific key frame for a specific element, it has to have like a still has to have a unique name. And then you often to generate a unique name, you have to use JavaScript. So, it would be neat if you could scope keyframes.
Wes Bos
But I think the the fix for that is at property in CSS.
Wes Bos
An at property in CSS will allow us to specify The type of a CSS variable, and that will then allow us to switch values of a keyframe. So you could say, like, you could have a length one, you could You could set the width or the height of something and simply updating the variable will make the keyframe update itself, which is
Scott Tolinski
not something that works right now unless you use app property. Everything is awesome about this. The keyframe thing, I don't have that many keyframe issues, overall. But, you know, I I wouldn't I would imagine people who are doing really complex animations do. You know, I've seen some interesting new animation libraries that or or doing, like, crazy town animations.
Scott Tolinski
Not like Butterfly Crazy Town, but just like you've entered Crazy Town.
Scott Tolinski
And the support for this, like you said, Chrome, Wes. Safari Tech Preview, Firefox, no.
Scott Tolinski
The sad story here is that there are there's not a lot of good ways to compile or polyfill this.
Scott Tolinski
There are ways to do Scott CSS currently in JavaScript.
Scott Tolinski
But, you know, this might be one of those ones you just have to wait for, which is Sad for me. I did see on this Firefox tip, just 3 days ago, there's been some movement on here. Safari announced that it will be added in 17.4, so it will be coming this year ish. I even have 17.4 on my iPhone right now as the 1st release candidate or beta or whatever.
Scott Tolinski
So it is coming to Safari very soon.
Scott Tolinski
And Mozilla has moved it to the ready to add phase here. So I posted a link to this standards positions.
Scott Tolinski
It is something that they're going to be doing,
Wes Bos
but who knows what their timeline JS. I'm actually surprised there's not a a polyfill for it because
Scott Tolinski
maybe There's a polyfill for scoped, but not for this. Yeah. Because, like, you could
Wes Bos
You could probably fill the scoping with just adding classes. Right? Like, you you back Yeah. But could you could you do this? You couldn't stop it, you Node? You probably couldn't stop it, and then you throw CSS variables in there and and maybe Scott. So Where's Jonathan Neal? We'll have to see. Yeah. He probably is is how to stab at it, but that's it. Thanks everybody for tuning in and we will catch you later.
Wes Bos
Peace.
Wes Bos
Peace.