Scope in CSS
Introduction of Chris Coyier
The host introduces Chris Coyier, highlighting his contributions to the web development community through CSS Tricks, CodePen, and the ShopTalk podcast. Chris is praised for his kindness and enthusiasm, and the host humorously suggests forming a CSS rock band. Chris is set to speak about the concept of scope in CSS, a topic eagerly anticipated by the audience.
Understanding Scope in CSS
Chris Coyier begins his talk by explaining the concept of scope in CSS, emphasizing that it is not a new feature but an inherent part of CSS. He illustrates how every CSS selector is scoped to certain elements, using examples like styling a carousel or applying styles to specific HTML elements. Chris clarifies that scope is fundamental to CSS and not a fancy new technology.
Challenges and Solutions in CSS Scoping
Chris discusses the challenges of CSS scoping, particularly in team environments, where overlapping styles can cause issues. He explains how naming conflicts can arise when multiple developers work on the same project, leading to unintended style overrides. Chris highlights the importance of scoping tools to prevent such conflicts and maintain clean, conflict-free styles.
CSS Modules and Scoping Tools
Chris introduces CSS modules as a tool for scoping styles, describing how it appends unique identifiers to class names to prevent conflicts. He appreciates the simplicity and effectiveness of CSS modules, noting that it allows developers to write regular CSS while ensuring styles are scoped to specific components. Chris also touches on the concept of co-locating styles with components for better organization and maintenance.
Scoping in JavaScript Frameworks
Chris explores how JavaScript frameworks like React handle CSS scoping, often through CSS-in-JS solutions. He critiques the lack of a built-in styling solution in React, which led to a proliferation of third-party tools. Chris contrasts this with frameworks like Vue and Svelte, which offer more straightforward scoping solutions, and discusses the benefits of these approaches for managing styles in large projects.
Web Platform Scoping: Iframes and Shadow DOM
Chris delves into the web platform's native scoping mechanisms, such as iframes and the Shadow DOM. He explains how these technologies provide strict scoping boundaries, preventing styles from leaking in or out. Chris highlights the use of Shadow DOM in web components, which allows for encapsulated styles, making it ideal for design systems and reusable components.
Utility Classes and Tailwind CSS
Chris briefly discusses utility-first CSS frameworks like Tailwind, which inherently provide scoping through class-based styling. He acknowledges the performance benefits and scoping advantages of using utility classes but notes that it's not his preferred method. Chris appreciates the efficiency of Tailwind's approach to minimizing unused CSS.
Introduction to the @scope Rule
Chris introduces the new @scope rule in CSS, explaining its basic syntax and functionality. He humorously critiques its initial simplicity but acknowledges its potential for more advanced use cases. Chris outlines three niche features of @scope, including donut scoping, which allows for more precise control over where styles apply within nested elements.
Donut Scoping Explained
Chris explains the concept of donut scoping, using the example of selectively applying link styles within content areas while excluding navigation links. He describes it as a more elegant way to manage style application across different sections of a webpage, highlighting its utility in maintaining consistent design patterns.
Proximity Scoping and Its Benefits
Chris discusses proximity scoping, a feature of the @scope rule that prioritizes styles based on their closeness in the DOM hierarchy. He illustrates how this can resolve issues with nested themes, where source order previously dictated style precedence. Proximity scoping offers a more intuitive way to manage style variations without relying on strict source order.
DOM Blasters: A New Approach to Scoping
Chris introduces the concept of DOM Blasters, where styles are scoped to their parent elements without explicit selectors. He demonstrates how this approach allows for component-level scoping directly in the DOM, offering a zero-tooling method for encapsulating styles. Chris suggests this could be a viable alternative to traditional scoping methods, especially for CMS-based projects.
Conclusion and Future of CSS Scoping
Chris concludes by summarizing the evolution of CSS scoping, from basic class-based scoping to advanced techniques like @scope and DOM Blasters. He encourages developers to explore these new tools and consider their implications for future web development practices. Chris expresses optimism about the potential of style block scoping to simplify and enhance CSS management.
Q&A with Chris Coyier
In the Q&A session, Chris answers questions about his preferred scoping methods, the potential of build-step-less components, and his thoughts on Tailwind CSS and BEM. He emphasizes the importance of choosing the right scoping strategy based on project needs and team dynamics. Chris also discusses the role of blogging and community feedback in shaping CSS features.
Speaking of handsome man, I'm about to introduce Chris.
Chris Coir. He's our very first speaker of the day.
You might know him from the one who started CSS Tricks back in the day. We've all visited CSS Tricks. We still are today. And you also might know him as the co founder of codepen. We've seen codepen being featured here in the decks many, many times. So I think that will definitely put a smile on your face, Chris. But Chris is also known for just being a nice person in general. Every time I see Chris, he's. He's smiling, he's like, just kind.
And you have that little spark in your eyes as well. So I like that, Chris. It gets you places. Be kind to people who'd have thunk, wow. Also, if you're into podcasts, you might recognize the voice because he also does the shop talk podcast together with Dave, Rupert, and then that's it. Sorry, that's all I do. It's those three things. Dad, father, you know, want to switch places.
And also yesterday we saw Brad run around with the ukulele.
Chris also plays an instrument. He plays the banjo mostly. And then Adam also likes to play.
Jeremy also likes to play. So maybe we should, like, start a CSS rock band or whatever. If we ever started one, Chris would be in it, definitely. But Chris is not here today to play the banjo. You are here to talk about SCOPE in css, which I'm very much looking forward to. So please give a warm hand for Chris.
Thank you very much. Brammer.
Sounds okay. Oh, my God. I knew a Dutch sound guy once.
I knew a Czech one, too.
I read that on Reddit one time. Scope is mouthwash where I come from, but whatever. So that's the joke. You're all intelligent people. I will dispense with the preamble. We're just going to talk about SCOPE a whole bunch, generally. Conceptually. If I was going to teach you about css, if I was going to explain to someone badly how, like, what the authoring experience of CSS is like, you might say it's. I don't know, you write some scope and then you write some styles.
That's what css. It's filthy with Scope. It's just all up in there already. Just in case you were wondering if we're gonna talk about, like, the new. Like, is it some new feature of css? Is it some fancy new technology?
No, it's not. It's just conceptually part of CSS to begin with. For example, every single selector is Scope. So, like, if you think of CSS as like, I got some sweet styles, I'm going to make this sick ass carousel. Good. That sounds fun.
You should do that. Where and when do you want to apply them to?
Which scope do you want to apply it? I was on the famous website CSSDay NL. Pretty good one.
There's some CSS that appears on that website. And hey, I know that deep pink is like the meme one that we're supposed to be doing, but I think named font sizes go even harder.
Do font size X large that rules.
They just ship that. That's the best. It makes me never want to use a real length again for font size. Anyway.
Cool. That scope right there, it's actually pretty hardcore scope. Those styles only apply to just the rare HTML element that happen happens to have class is date on it. That's pretty specific already. That's scope. So end of talk, you know, like, that's scope. That's scope. It goes further though. There's more scope. Like I said, CSS is lousy with scope.
They wrote some more styles that only apply it to screens.
Pretty specific ppk, I'd say, but okay, if that's how you want to roll. And then only on pretty big screens as well.
Scope, scope, scope, scope, scope, scope, scope. Everywhere out here in the real world, perhaps. Not that that wasn't a real website. Totally it was.
But here's another real website codepen. This is how it might go down. Let's say I wanted to style that little bad boy.
That's a day's work.
But anyway, I might be like, what is that thing?
I don't know. It's a card, I guess. I'm so uncreative. I just call everything a card. I am a card. Heavy dude. Cards are actually just little websites. Did you know that Dave said that once on the podcast?
I'll never forget it.
So, yeah, background gray. It's got some padding and border radius or whatever. Cool. I have now scoped that made a little selector to do that later on, I have to style that little component and I go in my little depraved brain and be like, what is that thing now? Is that a card?
Kind of looks like a card, but I don't know. The padding's a little different, the background's a little different. Doesn't have border radius. So I just scope it in my mind. I just feel like I'm not even going to use card. I'm going to use challenge card. And I have accomplished scoping just I've nailed it.
There's no conflict between those styles at all. I've just crushed. Crushed scoping. So good. In fact, the vast majority of CSS I've written by far and in my entire career was that that's all the scoping I ever did. If that's all the scoping you ever do, fine, Sweet. That's all you really need to know about css, I think. But it goes. We can go further than that.
In fact, we might as well, because I'm already up here. So let's go.
So the only reason to start piling on more tooling and syntax and crap to just that basic scoping already, which is learn CSS selectors, is when there's actually some kind of problem. A problem could be that I was tired next Thursday or whatever, and there was another little piece of UI I had to style and I was just writing all global CSS and I was like, what should I call this? I think I'll call it a card. And then this actually affects. The better you get at css, the worse of a problem. This is if you just rip out those styles card and you're just. You got it. There's a linear gradient and you nail it and it looks how you want it to look on the screen and you ship it. But you realize the you broke something else because your styles were perfect, but card was already being used somewhere else and you just weren't looking at that page at that moment. That's actually a problem, but that's you fighting you.
It's a little bit more likely on a team where you're not just yourself.
If it's like you're on a team of like two or more people, the likelihood of that happening is higher, probably like the bigger of the website. I know that's a little arbitrary, but it's highly possible that I style Card.
Rachel comes along on our team and rips out some card styles too, and we just don't notice and we cause problems that, like, does actually happen. I'd hate to say, you know, like, that's why people reach for scoping tools, is that we want to use simple classes like that, not strain our brain with coming up with totally unique names all the time and stuff. And there's also this. It's not quite as dumb as the Peter Griffin one or whatever, but it's similar that the bar stool problem in CSS is that, you know, you can do stuff in css. I mean, to explain the joke, writing CSS can have unintended consequences. Yeah, fine. And it kind, it kind of can. So I guess that's why we're talking about Scope also if you have like depraved ass CSS brain like I do, you look at that and you're like should have used text wrap pretty. You can't have orphans like that in public. That's crazy. And you can't do that. So we're going to look at some tools to take scoping a little bit further. Like a straight up warning. John was all like be like water man. And I'm going to be like, we should scope this shit out of everything. Just let's just push capitalism into whatever. I don't know. You got to pick.
So pick the cool one. I'm not going to tell you which one it is.
There's. So we are going to talk about at Scope and css. Probably most of you assumed that's what I was going to talk about. We'll get there, I promise. We're going to talk about it.
Gotta wait for Miriam to get here.
So there's some tools and the tools to apply scoping. Some tools are like just about scoping. That's the thing that they exist for in the world is to apply scoping to this situation. That's cool.
Pretty specialized tools. Some of them are. They involve the processing of HTML and CSS and JavaScript to pull it off. One of those technologies is CSS modules, which I really think is cool.
I legit think it's like a good project. I happened to click on the little contributors thing on it on GitHub the other day. It's having its 10th birthday, so it's Stephen Hayes birthday and also maybe CSS module's birthday too. Are you 10 already different?
Not your golden birthday, whatever it is. I do also like that they just, they just wrote it in 2015 and then just that's it.
Then they did nothing else. I looked at those 2024 commits like five minutes ago just to see what they were and it was some typos in the readme. I love a technology that's like it's fine, we just wrote it and now it's done.
So that's kind of cool. The way that CSS modules works is that you like, you write and I probably appeals to some people in this room because you just write regular css. It's just a CSS file and you write it and that's fine.
Like a Leah. And then it gets. Ultimately what shows up in the DOM is like that class that you wrote with some computer Gibberish at the end of it, which is the scoping part, because it's so whatever, algorithmically rare or whatever, that it's not going to conflict with something else.
My, like a little baby spicy opinion is that when you f with a language, when you change, when you add any syntax at all to a language, that you shouldn't use the native thing anymore, you shouldn't call it css. CSS modules has colon global and it has this other weird composes keyword. Well, you did it. You messed with the language, so don't call it CSS anymore.
I don't know. I don't have any more to say about that. But somebody in here is going to invent a language someday that's like a slight variation of css.
Just pick a new file extension.
It's getting processed anyway.
Spicy the way CSS modules works.
And it's only really relevant in JavaScript produced HTML anyway, so it's not on your just HTML and CSS website. CSS modules isn't really relevant. But what happens is that you import CSS like that first line, which is pretty much invalid JavaScript. You can't just import styles like that. There is a thing called CSS module scripts that kind of can, and it comes in as an adopted style sheet and stuff, but there's more syntax to it than that. If that is actually a CSS file, that would just be invalid JavaScript. But if you're in a tool that knows what CSS modules is, it's like, oh, I got it. I know what you're trying to do. What you're actually importing is just like an object that maps the class that you wrote to to the gibberish class. So the HTML class that gets produced has the gibberish on it. The HTML that gets produced has the gibberish on it. And now you have scoping. You have like good scoping that prevents all barstool kicking.
Scope. Scope has happened with CSS modules. Pretty cool.
I also like it because, like I said, it's just that the GitHub thing, it's just a readme, it's just an idea.
CSS modules, there's nothing in your package JSON, there's no cli, there's nothing. CSS modules is just like it should just work like that. And all these other tools are like, oh, that's cool, I'll just build it in, or whatever. I think that's just weird in technology today is to have a.
Have a thing that people think of in that way with no way to install it. What it generally looks like in the real world is like that's just a react component and you import the styles which does the CSS modules magic. You apply the class name to it in some way and then kind of crucially where you're importing it from is probably like right next to the component itself. So it achieves that like co location of styles. That's actually pretty nice. It means like the CSS in this file is for this component and they just hang out together, they're buds and they get thrown out together.
So that's what we'll talk about in a minute. I knew this guy I worked with for a little while who always used the word orthogonal and I was like, man, that is a fancy ass word. I looked it up once, it basically means related in the way he was using it. So let's all use the fancy one. There's an orthogonal problem that's called unused CSS and you can even open devtools and it'll be like, okay, you got like a 98, it's pretty good. But I see there's this little piece of CSS that wasn't used by anything and you're like oh, isn't it?
Well, you're looking at the homepage and it's used on the shopping cart page and, and now that CSS is cached so it's actually more efficient. So you know, whatever performance tool. It's a little hard to know actually if CSS is unused. So I don't really trust tools like that.
But anyway, this idea of like kind of co locating styles and scoping your styles is nice with unused css. I also talked to a team one time that all they shipped was global css for like 15 years, right? And you get this, you know your CSS only grows on your site and it was concerning to them. Cause it's actually a little hard to know what CSS you can throw away. It's not particularly hard to know when all your styles are co located. You either don't load that component, don't use it, throw it away, whatever. You have the git lens thing installed in your VS code. When you're on a line in VS code it tells you who touched it last. Sometimes I'm looking at some of our old CSS and I'm like woo, that was me a long ass time ago. I'm not touching that. That's going to stay right there for sure. So yeah, if you don't use in the co located styles world, it's like they're either not loaded or when you throw the component away, it goes away too unused CSS becomes less of a problem. That's kind of nice too.
This whole idea of CSS and JS probably wasn't invented just for scoping. It has all kinds of bad ideas behind it. But scoping is one of the benefits of it too, is that when you write CSS in that way, at least you're applying styles right to it. There's no barstool stuff going on, it's not leaking out and touching other crap. Mostly I mean CSS and React, because some of the other major framework libraries and stuff just shipped with a styling solution. And here's just another little baby little spicy opinion is that the fact that React originally shipped with no opinion whatsoever about how you style things other than like, I guess you can use css, otherwise you're on your own. Which gave birth to just this crazy ecosystem of CSS and React tools that as an industry, I don't know that we benefited a whole hell of a lot from. I don't think there was like so many good ideas baked into that that we're better off compared to like, Vue, who's just like, oh, you know how you do it? You just put a style tag, you want it scoped? Put scoped as an attribute and everybody's like, fine, that sounds great and I'll do that.
That's better. That's just better.
They do it in an interesting way where your classes or any selector, I guess, just your HTML elements that match, just get a data attribute on it and then it styles based on the data attribute, which is nice because it doesn't have to be a class and it maintains the class that you wrote on it, which is kind of nice because then it's like there's a user style sheet hook for it. That's not crazy. And subject to build process breakage and stuff.
Svelte does it too. How do they do it again, they do it with.
They just add a class to everything. They just add another class. So it just bumps up the specificity of your entire style sheet a little bit, which frankly weirds me out. But I've never heard anybody bitch about it, so maybe it's fine.
Seems like it would be weird for third party styles, but whatever.
So as the web platform though, like stuff that CSS gives you naturally, or like the platform as a whole gives you like, it doesn't really help with that. The reason we had to tool that away is because there is no Selector scoping in css.
It's not even talked about as far as I know. So scoping on the web goes from, like, super chill, like, I don't know, just write another class or whatever, to, like, very extreme scoping. So let's look at. Let's look at some hardcore scoping. There's iframes, iframe. Or as some people write it, the iframe or whatever. The iframe, which is my favorite way of writing it for sure, because I picture Steve Jobs like it's a rectangle.
That's awesome. They're hardcore. Because you put an iframe, you have some styles on that page. Those styles aren't going in that iframe, and no styles inside that iframe are coming out. That's about as hardcore scoping as you can get on the web. Pretty badass object.
Same deal, hardcore scoping. The web wanted to give us that for some reason. So now we have it. Now I don't have anything else to say about that. They're both the worst. And every business I've worked for profits mostly from iframe. So that's how that goes.
Shadow Dom. Do you see that movie with Keanu Reeves? That was pretty good for a sonic movie. I have a little daughter. Hey, rubes, if you watch this, Shadow Dom was how I first heard of it. Although it is kind of funny. Ooh, interlude. I hope I don't go over time because of this, but the first time you ever heard of Shadow Dom, I was talking with Jeremy about this earlier. The browser people were like, hey, you know, like, form elements, they're actually just built from css, HTML and CSS internally. Did you know that? Like, isn't that cool?
We just use the same stuff that you have access to, only also we put a huge brick wall in front of it. And you have to keep your grubby fingers out of it because we don't trust you in any way at all.
And you're like, why'd you even tell me that then? That's not even good to know. And then later they ship it in web components and you're like, you know that you can now do that to your users.
You love that. But I first heard of it from SVGs when I was on this crusade against icon fonts, which are bad. And I was like, there's an alternative way. You just put all your icons as symbols and then use the use element in svg and it goes and clones it and moves it down, but it puts it inside a Shadow Dom which had all these styling limitations, but it was still like a half decent idea. But now web components are like for the first time. And web components does not just like =dom.
It's a thing that you opt into if you want it to happen, but you can now, which is pool, so you don't have to use it, but you can. Here's a really simple web component where the first thing we're going to do is define it. So angle brackets, fancy button is like a thing now. And when HTML sees it, this JavaScript calls, the connected callback calls. It will run that JavaScript and what it's going to do is then that's the optional line that I'm saying. I want it to be shadow dom, which is going to wipe out everything that would normally render in there and says, all right, you're on your own.
Whatever you render in there from now on in this shadow root is the stuff that's going to apply. So I'm going to make a style element and jack it in there. But look at that, look at that water ass selector I'm using. Button. Little dangerous, isn't it?
Can't just slag a button selector everywhere. But it's cool because it's in a shadow dom so it's not going to leak out anywhere else probably. So there's fancy button and I have a button inside of it. That selector is now going to apply the one that I've put in the shadow DOM next to it. So it's going to render like, oh, super, super cool button, yay. But the styles aren't going to like leak out, as they say. So if I were to have a button that's in the same DOM as the custom element, it's just going to render like our old Brutalist buddy, the button, you know.
Sweet. That's cool. That's Scope. That was Scope given to us by the web platform. So cool. Thanks. You can imagine wanting to ship stuff like that as like a. I don't know, I don't even know actually.
But the baseline widget from Google, where it has the little browser icons and crap that tells you about a browser feature that has a web computer component and you would expect it to look like that. So it's got some CSS coming from somewhere.
I assume they ship it in a little shadow DOM so that your outside styles don't mess with it. Likewise their internal styles don't mess with anything outside of it, which would be an even bigger deal. So doesn't that sound nice for a design system? You have a design system and you have consumers of it who use your little stupid tabs component or whatever. It better look like tabs. So it's nice that they have co located styles that come along with the web component. Doesn't that sound nice for a design system theoretically? Maybe we should experiment with building design systems like that. Well, whatever. We don't have to experiment. Every major design system by every freaking company, big company, uses web components and shadow dom. So like they're already doing it. It's already. Here we go.
There's another kind of scoping that I don't want to say too much about because I don't care all that much. But when you talk about utility classes these days, it pretty just much just means tailwind. There used to be other stuff, but I think tailwind is pretty much well taken over on that. The expectation is that you style stuff with class names on the HTML thing. And some people say it makes them work faster. They can see in tailwind or whatever. It's not for me, but I get that.
What's kind of a byproduct of it is there's no styles there leaking out to anything else. That is scoping.
And scoping is kind of nice, especially on teams.
So it's just one of the benefits that you get from there there.
Okay, we have to actually talk about Scope though, because we only have so much time here. Let's rock some scope. Just credit to all the good people that write blogs and like, I don't.
It's not like I was involved with Scope. I don't know anything about Scope.
I know about Scope because I read a bunch of shit about Scope and then I made it into slides and I read it from the smart people who work on the websites. And if you have an RSS feed, I probably read it.
And if you wrote about Scope, it's probably in this talk somewhere. So just like it's just a general thank you to the people that publish on the web.
Thank you good people. If you're worried about the browser support kind of stuff, it's already flagged in Firefox, which is the only thing that doesn't have it yet. And it's an interop this year. So Scope is pretty much it's ready to go. I mean whatever. It's that use your own brain.
So here I'm gonna introduce you to the syntax of Scope and how stupid it is with a silly usage scenario that doesn't do anything useful. So you have that HTML and then you write some CSS that styles that HTML cool on the right. And then Scope is like, ooh, I can do that.
Also, look, instead of writing a simple card selector, you could write scope card instead.
And then the same thing applies. It's the same.
There's no difference between those things pretty much.
So you're like, thanks Scope, that's good job. Thanks for coming to the party. Did you bring any weed?
You could also browser test for it if AT rule was supported anywhere. I just thought that was funny earlier when you browser test it for something that's the supports test is newer than the thing that you're testing. So that doesn't work anywhere. It might someday, but you're actually like hurting yourself if you use that because then nothing's whatever. Don't do that. It is testable in JavaScript though.
Just put it in there. Because practical information is nice to have sometimes. So there's the basic usage of Scope where you do scope and then you do a parenthesis and you say what class you're scoping or what selector generally you're scoping. Not particularly useful in my opinion, although we will look at some use cases for it. But there are three baby little niche things that Scope does that I don't hate.
Anyway, sorry, I didn't mean to crap on it too much, but it was a little I really had to dig for to find some stuff in there. One of the things they can do is Donut Scope, which has a wonderful story because in 2011 Nicole Sullivan elegantly described why she would like to have Donut Scope in it. And I think that's cool. It's like a great web standard story. If you want something, you write a blog post and you wait like 15 years and then you get it. Which I feel like is pretty common kind of.
Anyway, she explained it very well in that blog post and good thing she did because we have it now. Here's just one use case that I think is mediocrely useful about Donut Scope. So here's an article on wired.com they appropriately use underlined links in the body copy of of their website. Cool. Links are underlined. It's in the user agent style sheet.
Keep them. Looks good for the most part. But there's a bunch of links on here that aren't underlined. Debatable, but maybe okay because the design affordance for navigation.
I guess I personally feel like that's okay that those aren't underlined, but whatever, let's move on from that and assume that that's the design goal that we're coming out. Some of our links in content are underlined.
Links elsewhere, in some cases are the way I've generally rolled. Like that is just like, leave the default underlining in place and then select the places where you want to remove the underline and do so. So it's like the like six shooter. Like, no underlines for you, no underlines for you. You know, Cool. Or you could go in reverse and you can wipe them all out of everywhere and then say, on the content, though, bring them back.
The opposite approach. That's fun. Isn't that fun in css?
What's the right answer? I don't know.
You can do it totally opposite ways. That must be why some people hate css. You're like, you can do it the exact opposite way. Yes, you can. Here's the Donut Scope way of doing it, though. You could say everywhere in the entire body, all the links. I want to remove the underlines until you hit something with content and then stop doing that. It's just like a slightly more elegant way to describe that same kind of thing.
So it's kind of like. I called it the Stop Caring Selector. It's like, care, care, care, Stop caring on the inside.
So in the pink area there, that's everywhere that the Donut selector is selecting. Then it stops when it hits the white area. So it could be your body area and you could apply it to all your comments below.
That's body copy. So it should have underlines or whatever.
That's the thing. That's donut scoping. That's what it can do. We never used to be able to do that in CSS and now we can. So sick.
Niche feature accomplished. CSS is just a little bit better because we can do that a little bit. Another thing it can do is proximity. It's super weird, but here we go. There's a classic thing where the demo for this is always light mode, dark mode. Questionable, but I'm not above it. I'm going to steal it. And then we'll look at one more example of it too. This is one way that you could implement light mode and dark mode. I don't even think it's particularly popular, but here we are.
Is to use class names on stuff to apply light or dark themes to it. So in this case you can just see it.
Theme is light or it could be dark. And now we have two classes.
We have a dark theme and a light theme class. One of them is, you know how dark themes work. I'm not going to read that. Thing to you.
But the crucial part is the nesting in there. It's saying links in dark mode are a bit brighter, lighter because it's on a dark color. And the dark blue maybe wouldn't work so well, whereas the blue in the light theme is a little bit darker. So great, we've accomplished that goal. It looks good on dark mode, it looks good on light mode.
We had to mess with the blue a little bit the same. It's not every color. But in this case it was appropriate that the blue was adjusted for those modes. But again, not always Mega, mega, mega common. But it's common enough.
You could imagine a site that's light mode and then the footer's dark mode or a it switches modes on a sidebar for like design contrast or something like that. It is possible that you use themes that are nested in some way, not like mega common. But hey, now let's support it and let's see the problem that comes up with a theme within a theme like that. We have the same exact css, but now we have a nested environment.
You know, we have some links that are nested between there. That one works.
Dark mode works. We have the light blue in the body copy and the dark blue in the white box. But this one MERP has failed because the source order matters here.
Like now on that bottom example, they're both dark and they're both dark because the links, even though they're in theme dark, the theme light a selector, those links are within an element that is themed Light 2. It's just the outer one. And so specificity is winning out here and it's screwing up those links. So like, I don't know, it's like a little minor bummer. So Miriam rolls in and she's like, I think we should fundamentally change how browser rendering works.
And now there's like this additional step called proximity that kicks in when you use AT Scope in css. So instead of just the theme, we're just going to make one tiny change, which is me backpedaling on the dumbness of it. It does have an actual feature or it does have something that it does when you use ATScope instead on a class. Now proximity is going to kick in. And proximity is a little bit more powerful than source order, but still less powerful than specificity, which was nicely represented in this chart that I confirmed just moments ago was by Bramis.
Good job. But you got to fix your kerning. There's a. Some issues in there.
See that? So when you're talking about Those teal links, specifically those links, that class that's closer in the DOM has higher proximity than the class that's farther up the DOM away. So now that we've done that, we've applied scope to those classes, it's cool in dark mode and it's cool in light mode, because now the source order doesn't matter. I mean, it's not that it doesn't matter, it's just the proximity matters a little bit more.
Cool we fixed the thing. Really what that means is that I think it's a nice way to stop caring as much about source orders, not worry about that. And plus, in a world of crazy bundlers and just in time loaded styles and all that stuff, to not worry about how the order in which that styles get loaded is kind of nice. You have a card class and a card big variation class on it. If you wrote it like that, you're going to have problems because the variation class you're kind of assuming in your mind is going to win over the base class. But in this case it wouldn't because the image there, the second one is going to win over some of those styles above it.
So instead be like, I don't know my variations, I'm just going to write as scoped instead so that the proximity of them is going to win over the base class. And then you don't have to worry, like all your variation classes, you don't have to worry about the order in which that they're loaded. It's a little bit cool, it's a little bit better CSS because of it. I don't think it's changing any lives in here, but it's pretty good. This is my favorite one though, for sure. DOM blasters. This might change everything. It might not. Let's find out.
There's some HTML, there's two divs in there, and there's a paragraph inside each one of those divs. One of these divs I'm going to slag in an angle brackets style tag.
And inside that angle brackets style tag I'm going to use at scope.
And no parentheses or anything. Not the double syntax of donuts, not even the single syntax of scoping one selector. Just nothing at all. Just at scope that will still have a scope. The scope is its parent element in the dom. SOPE is the div above hiho.
Here we go. And what I'm doing is applying some border to it, that div, and then selecting the paragraph within it and making it red. If we render that the first paragraph is untouched.
And the second one has all that red crap going on. So we've achieved some kind of like weird level of what's going on there is pretty interesting to me. I think it's actually pretty rad. So it's like selector scoping, but there's no selectors involved.
It just selects the parent element. So it's a way that you can pop some styles in the DOM that just to apply to one chunk of the DOM tree, you just rip that style in there and it works.
Wow. I guess that seems surprising to me. And it's not like the Shadow DOM and that you can still query selector through it and stuff. It's not quite like the Shadow dom, but it's like the Shadow dom and it's like you can just plop some CSS in there and it's just applying to this tree of stuff without even touching the Shadow dom.
I think there's probably people that have reached for the Shadow DOM for this kind of ability that you don't have to anymore. So it's like zero tooling way to do component level scoping at least, you know, pretty rad. There's some unknown, like, is that like, maybe we should just do that all the time is the thought that occurred to me.
Like, if you really care about scoping and you're working with components in any framework or anything, maybe the way to do this is to stop using so much tooling and just throw style tags where you need them in the Dom. The concern is that you have whatever, 10,000 elements on a page and they each have a style tag. What are the concerns about that? Is that bad?
Is the browser slow about it? Is there memory problems or DOM problems or whatever? I don't know that I nailed it, but I did put like 10,000 cards on a page and had it just use regular css. And then I had one where every One of the 10,000 cards had its own hundred lines of CSS that style it just to test it. And like, unfortunately, like, it seems like it's good testing, but I think browsers these days are like just so smart at crap like that that there was like no none difference. Almost like first of all, gzip or Brotli or whatever got in there and just.
It was like magic, dude. 18 kilobytes for 150,000 lines of HTML. That's some stuff that was pretty cool that that's what comes over the network. Of course, when it like unflitter fucks or however that works, that turned into big, a lot of stuff, but like the rendering speed of it, the performance, even the memory usage of the same one. One of them is little baby one with just regular CSS. Even though there's 10,000 cards and one of them was like much, much bigger, there seemed to be no difference. Okay, bad test. Because it's not. They weren't 10,000, like different elements with interactive styles and all this stuff. But it was kind of promising to me that I'm like, hey, maybe, maybe it is zero tooling action.
More likely what I think is cool about this and I'm going to use it is the, like, I'm just in WordPress and I just want to do like a little art direction on my post or whatever. Or it doesn't. It could be any cms, but the idea is like I just, I want this paragraph to be styled specially, but I want to just write CSS to do it so I can use media queries and hover states. I don't want to write inline styles necessarily.
I can just rip a style block in the middle of a blog post and have that and not think of a selector, not worry that that selector is going to touch anything else. All that kind of stuff is pretty cool. So that's as close to like selector scoping. That reason we'd reach for CSS modules or maybe even CSS and JS or something.
There used to be this old school style scoped thing I thought was pretty cool. In the dom, we got it back. It's basically back. If you saw that and you liked it and missed it, that we have that now, it's pretty much the same thing. All right, that's enough about scope. It was kind of too much about scope to begin with, so let's just do the little recap thing. First of all, CSS is naturally scoped.
Like your brains are already all messed up with Scope. If you're good at css, you're already good at Scope, you might never think about SCOPE again. You're probably amazing at it. So cool. Be just your good, good job everybody.
And also the second you're above like just solo warrior coder working on a website by yourself kind of thing. As soon as there's like two people, I'd say, like that's the line. You have any kind of team at all or the website gets a little bit big, it's probably scoping time.
Especially if you actually had a problem with scoping. A little light layer of tooling is probably appropriate at that point. And now native CSS scoping exists and CSS is slightly better for it. You know, it's okay if you're not extremely excited about it.
That's fair, I'd say. But it's cool. It's fine. Good job, Miriam.
It's more than I've ever done. I would tell people I met at a party, I'd be like, I affected how all websites are rendered in the world. What have you done? You know?
And that those style block scoping, I think there's future there. I think hopefully that like somebody in here is like going to look into that a little bit more. I think that's like underused. Like there's something there. Like there's something to that that could be used a lot more than it already is. Thanks so much to PPK and the Gang and CSS Day. Thanks for having me. Obviously, it's mandatory to Go Pro on CodePen and thanks for having me. Cheer computers.
Thank you. Chris, please join me. Oh, yeah, we do that with the lovely flowers.
Sure. They still look good, right? The flowers. I like them. I bet there's a hot pink one in here.
Don't worry about it.
Chris. Yes. Yeah, I should fix my kerning.
On the. On the. On the chart that you showed. We have a bunch of questions from the audience.
So Dolan asked, you mentioned a lot of methods to scoping. Which one do you recommend as your go to method and why? I think you gave a hint about it at the end. Yeah, just use different classes.
Chris's microphone is not working. No, it's because I screwed it up. We have somebody coming to the rescue.
Sorry I messed up your thing. The preferred method of scoping is just to use a different class name, period.
Subu asked is adscope inside of the dom, the DOM Blaster? Is it technically a new version of internal style inline style or.
I mean the only. It's different than inline styles because you get to write actual css. Like you can't write an inline style for a hover state.
Right. I'm pretty sure you cannot. So now you can. And that's one difference. It's just regular old css, I guess. Is that the question? Let's move on. Yeah, that was the question. And there is an open CSS working group issue somewhere where people want to put selectors into style attributes, which sound so complicated, but there is an open issue for that. Hands off.
Cool. Cool. You grunted.
Hardcore scoping. Can you do that again? I liked it. Hardcore scoping.
Could you do full talk that way?
I'll get you next time, Gadget. Maybe we shouldn't we were in a former church, maybe we shouldn't do that at the end you mentioned it was in your overview site, the purple one.
I think you mentioned something like maybe we can get into this build step less type of components in the future. Is this something that you would like to do eventually get to or do you see. Well, isn't that fun when the web platform comes in and it's like, you know that thing that you used to use a tool for, now you don't need to use a tool for it again. That's like my favorite kind of platform development. And that was what's on my mind. When you looked at the, the style tag thing you're like, normally we have to use tooling to get that kind of scoping and now maybe we don't.
Can we lean into that a little harder or is the tools doing so much more that we should just keep using the tool? And it just seems like early days to know that. But maybe do you have a thought of like what are the things that are blocking you to getting there?
I mean it would be knowing what the full performance story is like. Like what if a webpage didn't even have a link tag to any CSS at all?
Every single piece of CSS that styled say fairly complicated website was a style block inside of each component. Like a real world website. Is that tenable? Like how does Chrome do, how does Firefox do, how does Safari do? Are there differences in the browser story? Is it like faster? Because CSS itself is like a blocking resource and maybe because it's not a blocking resource, maybe if streaming HTML is a thing, maybe it is somehow better even.
I don't know. That's the interesting story about all this is like what if we just didn't have the sheets part of CSS related to that? There is an add sheet proposal somewhere that is doing rounds. Microsoft is proposing it where you can define like a block with some styles that don't apply and then you can IM import those styles.
Maybe that will solve maybe the problem and maybe the next year you can come talk about it. Yeah, yeah. I mean I could imagine a world in which you write a. I think they're called CSS module scripts. Right. So instead of actually including the inline block of styles that it's still just an import statement but it's scoped anyway because you.
I don't know. That seems far fetched. I don't understand how like I really don't actually know if that's a good idea or Not. It just occurs to me donut scoping back in the day also might have seemed far fetched.
But like as you mentioned, like blog about it and then wait 10 years and then we have it. Yeah, I saw you mentioned at rule the atrual function to check what is that real? Was I right?
You know, stuff. Is that real? That thing exists in a working group resolution, I think. I think it also exists in the spec. But yeah, it's one of those ones where like, okay, we decided we're doing it and then nobody does it. It's behind the flag in Chrome right now, but there's some open issues with that.
Is there advice that you can give to people because you now mentioned AD rule. One of the things which I interpret as a hint of you want this.
Is there advice that you can give to our audience right here. Like, hey, if you want a certain feature to happen, what should they do?
I know what you mean, but I'm not super sure you're closer to that stuff than I am. Like, what should they do? Should they like thumbs up the GitHub issue or. Yeah, one thing I don't know.
Yeah, I mean be heard I guess. I mean blogging goes a long way, so maybe we'll do that. Do the blogging. Yeah. And then if you add an RSS feed to it, which you should, then I will read it.
So win. Win.
Oh, this is crazy. Like this is a live doc, so there's more questions trickling in and layout is shifting around. Like we have cls. I think it's web sockets or how does it work? I don't know. Technology hooray.
Maxim is asking how do we feel about Bam in 2025?
The City of Bend, where I live. B E M. Sorry.
Bem. Yes. Block elements modifier thing. That is weird. I was never super into bam. I get it. It was the idea of flattening scope. So it's related to my talk. I guess the idea was let's not write so much nested css. Let's have even the internal elements just become a class selector so that the specificity was flattened out, that everything just had that class level specificity.
So overriding things became easier. I don't hate that as a concept.
That's kind of smart, I guess. But it was really strict. I feel like there was wasn't even like, wasn't it Yandex behind it like this Russian search engine and anytime I mentioned it in a blog post they would email me immediately and be like, you should link to the official Yandex documentation for bem. And I'd be like, I will link to what I please to link to.
You know, it just was weird. It was like something about bem, like, turned me off from, like, a society perspective. I think they're reading your RSS feed and then that's how they get the info.
Yeah, maybe. But whatever, you can bam it up. It's fine.
It was just a convention. It was like double underscores or double dashes. Cool. That's it. Like, if that's how you want to roll, roll like that.
Maybe I'll use single dashes, which tailwind uses. Which is a nice segue to the next question.
Like, Rick. Rick is asking, like, okay, what's your. This is a spicy question that we saved for the last. Right. What is your honest opinion about tailwind and the way it scopes? I don't know, it's just not.
I always do that, like, let's do the sandwich technique where you say something nice and then you say something mean and then you say something nice again.
No, that's not what I'm going to do. But it has cool performance characteristics.
I always thought it was cool that, like, it, like, reads all the classes that you used and then produces the smallest possible CSS style sheet that accomplishes all the classes that you're going to use. And it ends up. It's probably smaller CSS than I would write, or we would mostly write. That's cool. That's a good performance characteristic of the thing. And if you are, like, spiritually can look at tailwind classes all up in your HTML and be like, that is working for me. What do I care? Good job. I always just didn't like it. And I like that it's like, I already know css, but it's an abstraction over CSS that constantly has to keep up with the language of css. And something about that bugs me, too. And, like, how do I express media queries? Well, obviously they have a syntax for it, but then it's like I'm writing a bunch of styles and then I'm writing them again with, like, MD colon on it and stuff. It just. There's something about it that just. It just bugs me syntactically.
But I don't, like, care that it exists. I'm just not into it, you know? Thanks. And with that, please give a warm hand for Chris.
- CSS Selectors
- CSS Property: font-size
- Media Queries
- CSS Property: border-radius
- CSS Class Naming Conflicts
- CSS Unintended Consequences
- CSS Modules
- CSS Modules Build Process
- CSS-in-JS
- React CSS-in-JS Libraries
- Scoped Styles in Vue
- Selector Scoping Limitations
- HTML Element: iframe
- Shadow DOM
- Web Components
- Utility Class Scoping
- Tailwind CSS
- Browser Compatibility for @scope
- CSS Donut Scope
- CSS Proximity
- CSS Source Order Concerns
- DOM Blasters
- Style Tag Scoping
- Native CSS Selector Scoping
I hate to be the one to tell you but writing CSS is half thinking about scope. You don’t always need them, but there are plenty of tools out there that help with scoping one way or another. They are worth considering as they help with a variety of problems a team can run into while building and maintaining a website. CSS itself is getting in on the action with @scope, a relatively new at-rule. It’s got some interesting tricks up it’s sleeve, but doesn’t do the same sort of things that build tools can do related to scope. So I guess we’d better talk about it all together.
Sketchnote by Artem Pendiurin
