Skip to main content
807

August 12th, 2024 × #css#components#styling

CSS Components: Tailwind, Panda, Scoped, Modules, Classes, Variables, CSS-in-JS and Sprinkles!

Scott and Wes discuss different approaches to authoring component-scoped CSS, including class-based systems, BEM, CSS modules, utility classes, CSS-in-JS, and more.

or
Topic 0 00:00

Transcript

Scott Tolinski

Welcome to Syntax. On this Monday, hasty treat, we're all gonna be talking about component CSS.

Scott Tolinski

What are the different approaches to authoring CSS inside of components and, in general, how that component based CSS workflow can work within your application? We're gonna be talking about all different types of approaches that people like and use, and just some a little, some of our thoughts on them and maybe what differentiates them. My name is Scott Tolinski. I'm a developer from Denver. And with me, as always, is Wes Bos. What's up, Wes? Hey.

Wes Bos

Excited to talk about this. We've we're just going through, a show called CSS authoring approaches, and I realized, like, we're kinda all just talking about components with all of these. So we switched it to we're all pretty much making components at the end of the day. Right? Like, even if it's a website or a web app, you're all just, like, thinking about, I'm working on this piece right now. The header. Global CSS. Yeah. Yeah. But there's many many ways to sorta get that job Deno, so we're gonna go through, all of those today.

Scott Tolinski

Yeah. There's a, what did they say, a 100 ways to skin a cat? I love that neither of us, are good at saying, so I'm just gonna go with Yeah. Something like that. A 100 ways to ESLint. There are more than what oh, there's more than Node way to skin a cat.

Wes Bos

Yeah. Yeah. I don't think there's a 100. That would I would not be able to figure that out if there was a100.

Scott Tolinski

I don't even want one way if we're being entirely honest. But I do want one way to solve my bugs, and that is centurycentury.i0, the perfect place to solve all of your bugs, but not just your bugs, your performance issues, anything that you might have in your application. It gives you visibility, to fix the things before they become a problem. It it really empowers you as a developer to solve your problems, to make better things without having to really worry about what's happening, who's it's affecting, whatever. You get all of that and more. So check it out. Century.ioforward/ syntax.

Scott Tolinski

Sign up and get 2 months for free. It's just a incredible service. So CSS components authoring systems.

Scott Tolinski

Let's talk about, first and foremost, what makes, you know, a good component system Yeah. For CSS? And one of the things that, for me, is really a must have for component based CSS is being able to and I know you don't even have this in the notes here. Number 1 for me is being able to scope things if I need to, To scope to a component itself, to scope to several components wide, you can scope from a very wide range to a very narrow range. And that, to me, is one of the essential features of Mhmm. Component based CSS.

Topic 1 02:10

Component CSS should allow scoping styles from wide to narrow ranges

Wes Bos

Other things is a reusable component is obviously good.

Topic 2 02:49

Good component CSS has reusable parts

Wes Bos

You want to be able to define a whether it's a card, whether it's a avatar, whether it's a button.

Wes Bos

You want to be able to define the CSS for that button and to be able to reuse that consistently throughout the website. So no matter where you put that thing, it's going to look the same. It should also provide an API for predefined styles.

Topic 3 03:18

Consistent styling helps avoid messy, fragmented CSS

Wes Bos

Good component CSS is half of it is just about being consistent. Right? Because that's why websites tend to get messy and sort of run away from you when you have too many different tweaks here or there. Like, you can kinda feel that when you go on like, PayPal is a great example of this. If you go on PayPal's website I know I always rip on PayPal, but I'm I'm coming off a a bit of a couple of rough weeks with them. Yeah. I get it. Yeah. You go to their website, and and, like, some of the stuff, it looks a little bit different than the other stuff, and the spacing is a little bit odd. And then, randomly, there's just, like, Times New Roman font somewhere, and, you can tell that likely and and this is just part of having a a very large backlog of in a very large company, but you can tell that there's no there's not a great way to to choose from predefined style. So limiting the selection is often a frustration, but it's a benefit to a component of you can just choose from a set of predefined colors, sizes, font sizes, breakpoints, light and dark, things like that. Yeah. It's systematizing

Scott Tolinski

your things in CSS. Because if you show up to a component and you write background color, the pound f three f whatever, and then you do font size 16 on this thing and whatever, And then all of a sudden, you change globally some of those things or even you have global things already for that. You now have to go in so many places anytime you've authored exceptions, overrides, and things like that. So exceptions and overrides to the system need to be very intentional and very purposeful rather than, something you're just willy nilly tossing around.

Topic 4 05:02

Components should compose well, like LEGO blocks

Scott Tolinski

Another one is they need to be composable, especially in componentized world. We often talk about components as being LEGO pieces. Right? You can put them together. Node of the cool things about LEGO pieces is many times, you can put the alien head on top of the golfer's body. You can put a door onto a spaceship. You could do that, and it works. And so they need to be composable in a way that it all works. Right? If you're, like, you have as an example here. If an avatar goes inside of a card and that card could possibly be inside of a table, that all needs to adjust.

Wes Bos

I know you said this, but real quick, variations and overrides allowing for them, that's a kind of a delicate dance because allowing for too easy of override will cause, like, splintering of your styles throughout your website, and that doesn't look good. But you also do need to sometimes allow for variation Wes, yeah, I I do need to be able to put a different border on this thing because of this specific use case. And the last 1 we have here is just dead code elimination or, like, in my opinion, a good CSS component system will only bundle the CSS that is actually used. If you're looking at your your CSS somewhere and you say, am I using this CSS on the page? How do you answer that? Right? Is it well, like, I can search for the class throughout my thing, or I don't know what's being used and what's not being used. Better ship it all. That's how you get really bloated bundles of CSS at the end of the day. Whereas, like, we've sort of solved that in JavaScript land Wes you simply just require the JavaScript you Node, and if you stop requiring something if you stop using a component, then all of the dependencies of that component will no longer be thrown into the bundle. If you just have 1 big CSS file, you might not necessarily know that.

Topic 5 06:51

Eliminating dead CSS code is a hallmark of good component systems

Scott Tolinski

Yeah. And that's what I love about writing your styles in a component, whether that is in a single file component system or even just any way to keep those styles collocated with that that component because it it makes that process much easier. Right? If you load the component, you're loading the styles. And if you toss everything in a big global style sheet, you're just loading that the whole time no matter what. Another thing that's really great about single file component with CSS is that many times, it's easy for the system to tell you right then and there if an attribute is not being used. So, like, for instance, I know you probably does this. Svelte does this.

Scott Tolinski

If you have changed your HTML and the CSS you have down below has no longer matching it, it will tell you with a warning in your ID, but also in your your check process, this style is not being used. And you can quickly know a hand like, alright.

Scott Tolinski

Why is this here still? Did I break something? Did it change? Do I need to modify it? It just helps you get a better understanding about what's going on inside of your CSS.

Wes Bos

So before we get into it, I have a question for you JS, how do you decide what is a component and what should just be part of a component? So, for example, if, you have, like, a heading of a show, and inside of that heading of a show, you wanna put, like, a little pill that shows how long the show JS. You know? 52 minutes and and 43 seconds. That pill itself is sometimes used in other places on the website.

Wes Bos

What's your do you have any process for figuring out Wes does something become just part of a component, and when does something need to be its own component which can be added and composed upon?

Scott Tolinski

Yeah. Some of that comes with practice and knowing what will bite you later down the line. You know, I've had situations where sometimes a a tag or a pill or something like that makes more sense to just be a class, like a single class.

Scott Tolinski

Is this thing really just a span with a class, or is it actually a component? Sometimes in in my my history as a web developer, I would make that span with a class a component and scope that 100% of the time. Nowadays, I would lean more towards a class for some things.

Scott Tolinski

That said, I do think it is a feel thing, and it also depends on how much this thing is going to be reused and how many variants of this there are they're gonna be. Let's say you have a pill. That pill could have an icon. It could be different colors. It could have different sizes. Then I'm going to look into making that into a component with props to adjust those types of things. But if it's just a single

Wes Bos

span with it, some styles applied to it, sometimes a a class is all you need there. Yeah. But in in your in your description there, the kind of is its own component, because that's our first one. It's just class based components, meaning that Oh, Wes. Instead of you saying, like, heading, space, span to select the the span there, you're giving it its own class of, like, a pill. I would say that that's making its its own component. You're not putting it in its own file and making it, like, a reuse I guess it is reusable because you just if you wanted to use that somewhere else, you would just reuse that class. Right? Yeah. Class is inherently,

Scott Tolinski

reusable, and it's tough to like, when we're talking about, like, a class based component system. Yeah. It's tough to align that when we're talking about a React component or a SALT component. Right? Yeah. Because they they kinda feel, you know, separate. With a class based component system, one of the things you're doing is you're typically going to be authoring that style in a global manner, in a global CSS file. And it's much harder, I think, to do dead code elimination that way Yeah. Because you're going to be loading that pill no matter what.

Scott Tolinski

Otherwise, like, how how would you know you're bringing in that class only when a pill's used? Then you're probably already reaching for an actual,

Wes Bos

like, JavaScript component. So the first one, class based, is simply just you give you have an element, and maybe you think, okay. Well, like, this is my card component, and this is the h two class that goes inside of or a heading class that goes inside of it. At a certain point, you think, okay. I'm gonna reuse that, or it doesn't make sense to tie these things together because it makes sense to put it in its own component. Pretty popular way to do this, and I know it's a little bit older, but I still see it used quite a bit on websites, is the the BEM approach, which stands for block element modifier.

Wes Bos

And the whole idea there is that you have your block, which is your your main component. That might be a card, and then you have an element, which might be, like, your card heading, and then you have your modifier, which might be, like, card heading extra large, which is is much larger than that. And there's many ways to sort of approach it. There's object oriented CSS. They're simply just giving stuff classes and styling it how you want it. Especially Node that we have nested CSS, this approach actually is a lot easier because you don't have to give absolutely everything a class.

Wes Bos

You can simply just write your nested CSS, and it will be applied to the parent that's there.

Scott Tolinski

Yeah. And this can get you into trouble. If you if you nest too many things, you could be, not taking advantage of the reusability properties of CSS. And next thing you know, you could be getting into a situation where your your code is sopping wet. It says having a hard time where you're anytime you wanna change anything, you gotta worry about all of the different nested versions of this thing that you have written and scoped to those classes. Little bit different. That's why Yeah. The rule of thumb is everyone always says, like, don't go don't nest deeper than 3. That's sort of a soft rule. There's plenty of situations where you would go there. But if you find yourself nesting more than 3 levels deep on a something,

Wes Bos

you probably should ask yourself, should I stop? Should this be its own class? Should it be its own component?

Scott Tolinski

Yeah. And then for a long time, folks, if if you're newer and you've only ever written React code or anything like that, for a long time, BEM was the you know, there was a couple other ones that were, like, really prominent, but BEM was really the law, essentially, if you wanted to write really well defined CSS that was easy to update, easy to find. And, honestly, I think that might have been some developers' introduction to actually working with something that could be considered a component even if we didn't recognize it at the time. Right? We had blocks.

Wes Bos

Next approach we have here is CSS modules. The way that this works is you write your CSS for your component in a Scott module dot CSS file.

Wes Bos

And what you'd then do so you might have, like, a Scott card in there, and you simply instead of adding a class to your markup with a class of card, you import that CSS into the component when you're writing your HTML or your JSX or whatever you're using for templating.

Wes Bos

And by simply importing that, you'll be you'll have access to all of the selectors from that file. So for example, if I have a card .module.CSS and I have a selector in there that's Yarn Mhmm. I can then access the .cardstyles by saying import styles from card dot CSS, and then and then you get a generated class name, which you can then pass in. So the reason we do that is so that everything is absolutely unique and scoped. You don't have to worry about overriding.

Wes Bos

Like, if you have a classic card and then somebody else has a classic card in another module, it doesn't matter because the the IDs at the end of the day are going to be generated, and they're not globally available. So you simply just import it. It will give you a a generated class name, which you can then apply to your markup. And then the added benefit to that as well is you get the really nice dead code elimination because if you don't import a module, it's not making its way into your your global bundle. I've not been a fan of

Scott Tolinski

CSS modules myself. I was actually surprised to see that, like, JavaScript has first party support for that type of thing Mhmm. Via the the import pnpm. But I don't know. Have you have you ever been a fan of that? I'm gonna say it straight up. I don't I don't get it. I mean, I get I get it, but I what I Yeah. I I don't I don't get why you would like this. I don't like it. There's a lot I don't like about it. It just feels like so heavy handed for what I expect to work. It it feels like you remember the 1st time you used Redux and you're like, man, this feels like too much work for what I'm doing? That's what it feels like to me. It's like I've written scoped CSS in a much cleaner way. Yeah. And I I don't I don't feel like I need to go the long way to do this type of thing. And Yeah. There's so many better approaches,

Wes Bos

in my opinion, that I'm not that's probably why I'm not a fan of it. So the next one we have here is Scott CSS, which is probably, I would say, Scott and I's favorite in all of these use cases. Would is that fair? Yeah. You know what? I would say JS a blanket statement,

Scott Tolinski

just about all of these techniques are trying to solve the problem of scoping your CSS. Yes. Because now that we're building Lego pieces or blocks or or things, now that we're building chunks, Being able to say this chunk looks this way is, like, in in the entirety of what we're doing with CSS in a component. So by default, all components scope their CSS and Svelte, and you have to specifically say that this CSS is global for any selectors that affect things outside of that component, which it in itself is kind of a code smell and that you're probably putting that into a a global CSS file instead of using the global. I know some people might feel differently about that. View has a very similar concept, except for there's this kind of the opposite where you specify that CSS is scoped by using an attribute. So So you throw an attribute on your style tag, and, therefore, that CSS will now be scoped. Web components, via the Shadow DOM, CSS is scoped to that component. And, also, here's another huge one, big addition to CSS, and this is gonna change things for a lot of people. In fact, I would imagine and and I don't have anything to suggest that I I know this for certain. But I would imagine systems like Vue and Svelte are going to start using this technique once it's morely widely available. And it's the at scope at rule in CSS, which, surprisingly, I didn't know this, now has 82% browser support with support in every browser, including Firefox behind a flag. So at scope is on the precipice here of being available to us all. And we'll have some links so you can check out how at scope works. But it's basically you use the at scope rule. And inside of parentheses, you're throwing the selector you want your CSS to be scoped to. You can also do Sanity scoping where you have a limit, where that limit JS. You could think of the the bounds in which the the scoping is applying, and you could apply, CSS outside of that scope by going inside. It's it's a dominant metaphor. Yeah.

Wes Bos

Man, it just hit Chrome for Android, like, at the time of recording, 3 or 4 weeks ago.

Wes Bos

So yeah. I haven't looked at this in a while. We're gonna start seeing we did a whole whole show on it, but at the time, it was just hitting Chrome. But now taking a look at it, it's hitting Firefox very soon. It's been in Safari for 8, 9 months already. So it's it's gonna be a little bit more, before we hit it, but I'm excited for this specifically because one of the things I don't like about the way that Svelte does CSS is that if you have a component that applies some CSS, the CSS is only applied to the elements that are in that component. If you have a child component that maybe renders out a span or something like that, in order for you to style those, you have to move the CSS to that component, which in in most cases is is a good use case. But every now and then, I'm like, no. I just wanna be able to style the the children with this class name Yes. The children is the thing. Yeah. Inside of the parent, I wanna apply some styles to it, and it it doesn't work unless you explicitly global it. But with the CSS add scope, there is this idea called the donut scope. So by default, scope will go start where you want it, and it'll go all the way down, which is maybe not what you want because you could you could apply some CSS to a card component.

Wes Bos

And then all of that card components like, let's say you style a span or something.

Wes Bos

It's gonna go all the way down to every single element that is inside of it. It will not stop, but you can use until in the CSS Scott. It's called donut scope. So you can you can define where it starts and Scott. So you can you can explicitly stop the cascade

Scott Tolinski

from going on down. Yeah. It's so funny. When you when you were saying it goes down, you did like that like this, where but in reality, it's more like this. Right? Because you're narrowing as you go down. Right? Oh, yeah. I was doing this, like the Dom tree Okay. The Dom tree. I'm thinking like this, and then you could think of donut scoping as you're just, like, shaving off that that that point Yes. Or something like that. Yeah. Wes. We're doing calculus here or whatever. So okay.

Scott Tolinski

CSS and JavaScript is also a big strategy for this type of thing. And many people had an introduction to this with something like styled components, where you're essentially you're writing CSS in a string in a template tag literal, and that just becomes your whole component. The component could have props that you could then use to modify your CSS, which, largely, that technique is being replaced by CSS variables.

Scott Tolinski

But it's a simple way to create a quick component that expresses CSS and scopes it directly to that component.

Scott Tolinski

At one point in time in my life, Wes, I had an a capital h one, h two, h three components. I had a Yeah.

Scott Tolinski

A p component. I had an a component, and it got exhausting doing all of that. So nowadays, CSS and JS has changed a little bit given that, you know, we have different types of of platforms out there. You took a little bit of a look at Panda. I don't know much about Panda. Is it different than style components?

Wes Bos

Yeah. So style components and, I'll say, the rest of them, like, there's emotion, and there's there's lots of style components sort of was the big one. Right? The way that they work is they were all runtime, meaning that they had to run-in the browser, and then it would apply the styles to your page. Right? And Panda is like, we don't really necessarily need it at runtime anymore because in order to make your CSS dynamic, you just use, CSS variables now. Right? There's very few use cases where you would actually need dynamic CSS. And if that's the case, if you really do need dynamic CSS, then just put it in a style prop on your component. Right? Just use an inline style or ESLint style object. So people just really like style components because it gave you the Scott of the same experience as as Svelte does is I would just make my div above my actual component, and I would say, like, style dot div, and I put all the CSS in it. And then right below it, I do the actual, like, functional, component of, like, what does it do and how does it handle click handlers and whatnot. And I'd be able to have them in the same file if I wanted to, or I could just throw it into another file and make it reusable again. Right? It's just a nice way to scope it, nice way to author it. With Panda now scope wrapper, really. Yeah. Yeah. Exactly. With Panda, they provide a whole bunch of stuff. Right? That they have some stuff around design systems. They have a lot of, like, helper patterns as well, which is both you can make components where you can reuse them, but, also, they have helpers for making stacks of of content. So instead of having, like, a display grid and putting a gap between each of them, they have this idea of, like, an h stack, a reusable everyone's building this. Right? And there's there's circle. There's center. There's a whole bunch of helper patterns along with that. And the kicker is that Panda runs at build time, meaning that it's not it's no longer a a runtime thing like style components is and both with server components as well as people are realizing I don't need my my CSS to be computed at runtime. It's really nice just to do that all at at build time.

Wes Bos

Yeah. Totally. The the Panda API and and CSS and JS APIs can look a few different ways. Like, you can have tag template strings, which is is my favorite because it looks like you're writing CSS.

Wes Bos

You can write the same CSS you're used to. All the nesting works. All of the stuff you're used to in CSS works in CSS and JS, but then there's also popular ways of using a prop based API. So you have, like, a a card component.

Wes Bos

And if you wanna specify properties of that card, you would just pass in, like, size equals 12.

Wes Bos

Ray Radix UI is is similar to this as well. Instead of passing CSS, you're just passing properties that have been predefined.

Wes Bos

You can pass across.

Wes Bos

And then finally, you can also pass style objects as well, which I've never been a fan of myself. Same. Writing your CSS as a JavaScript object. I I understand that you can get used to it, but I rather write my CSS as CSS.

Scott Tolinski

Yeah. You can you can move CSS as CSS places. Where CSS is an object, you're limited to keeping it as an object forever. I guess now with LLMs, you could probably tell it just to convert it for you, or maybe there's extensions to do that type of thing. Yeah. There JS, but it's still and also the Facebook one as well,

Wes Bos

which was what's we did a whole show on it. Stylex.

Wes Bos

Stylex. Yeah.

Wes Bos

They do a similar way where they Facebook will Stylex will have an object of the properties

Scott Tolinski

and pass it along. And a lot of people like, I don't really like I don't like writing my CSS that way, but everyone's like, you get used to it. Yeah. I I'm gonna say I don't get this one either. I've never gotten it. I know JS people or even, like, actual developers who don't like CSS, I think, gravitate this to this a lot more. But folks who got their start writing CSS,

Wes Bos

HTML, those types of things, I I just I've never gotten the argument for using the objects unless post your like, you have, like, a Node you find, and you wanna you wanna use that CSS, and yours is Yeah. You gotta convert it. You know? It's just a that's annoying.

Wes Bos

But next 1 we have here is utility CSS, which is instead of writing CSS as, like, a selector and all of your your properties along with that JS you have a whole bunch of utility classes, Tailwind obviously being the very biggest one in this space, and you simply just apply all of your so you want a border. You want rounded corners, you want font size, you apply classes that are associated with those style properties to your element directly.

Wes Bos

Sometimes they match 1 to 1 with what CSS is, but you kinda have to learn a new set of classes for it. And then it will also often include a bunch of helpers for things like spacing or adding rounded corners or or, light mode, dark mode, media, breakpoints, like, different, like, different variants of that element that you have.

Scott Tolinski

Yeah. And and Wes guess some of the downsides here is obviously that you end up styling a lot in your classes, which can lead to wet code where you're just having the same classes being used. It can pollute kind of HTML. Those are some criticisms of something like this. It's no longer a utility if everything is a utility, I guess. But, you know, there's a lot of upsides to it where you are able to define it's a system. Right? The utilities are a system. And if you're using the system, that inherently makes for things that are they work better together or they they feel better together because it is obviously a system. I think there's a lot of interesting ones. There's UNO CSS as well, which is an on demand atomic CSS engine Wes it gives you a little bit more customization in terms of what kind of classes you're actually shipping, for your utilities and how that all works. I I think there's a lot of really great things about utility CSS and utility based CSS. I I do think there are some difficult things. Because one one thing the way that I look at this is that CSS itself is a very full featured language. And when you move to a utility class based DSL, which is what these things are. Right? Yeah. You are at the whims of those classes now implementing CSS things. Now granted, you can use normal CSS with Tailwind all you want. There's no problem there. But now you're mixing multiple approaches, and you just have to think about, you know, what the implications of all that is. So, you know, I'm not saying it's a bad thing. I think I think it's, you know, different strokes for different folks. You know? I just see that JS, like I don't Node you want me to get into j s sprinkle or, sprinkles here now? Or No. Well, like, real quick on on, like, the Tailwind thing is

Wes Bos

I wrote my latest website in in Tailwind as well, and I'm a big fan of it mostly because of the ability to do arbitrary styles, meaning that you can sort of break out of the the predefined, situations. And, like, also, like, something like like p dash 4. Like, I don't know, like, how many pixels is that. I realized, like, there's a scale, and you can change it if you want to. But I much just rather prefer pass to rem or or 25 p x or or something like that. So and I find myself like, I do have a fairly lengthy sort of breakout CSS file where I'm like, this is much easier to do in in its own CSS file, adding a class to the thing rather than having to figure out what the equivalent is. And and most of that stuff is a lot of the the new CSS

Scott Tolinski

stuff coming. Queries or, even anytime there's anything new, there's a a wondering of, like, how could you possibly implement this in classes? And then, again, it's like a it's a DSL at the end of the day. And I think Yeah. With any DSL, knowing the ins and outs of a DSL is kind of like and that's a domain specific language for people that are Node. Knowing the ins and outs of that is learning yourself. So if you already know CSS and these new features as CSS, now you have to learn a whole subset of this DSL to be able to work effectively. And so I I think those are all just trade offs you get with the the power of the fact that you have a full system now that you didn't have to write from scratch.

Wes Bos

What this Node, I've not seeing this UNO. What is this? Guess who UNO is from? Ant Foo. Just Wes.

Scott Tolinski

You could just tell by looking at this page.

Wes Bos

So what's what's the idea here?

Scott Tolinski

It's less that you have a fully predefined utility system and more that you can create a utility system. So it's allowing you to create your own tailwind like system without having it be totally predefined for you.

Wes Bos

I don't know. It's If I could make a good system, though, I would probably just make a mess.

Wes Bos

I you know what? I'll tell you what? Making systems is one of my favorite things in the whole world. So this this speaks to me if I wanted to use this type of thing. Oh, okay. So Yeah. It it's kinda like if you were using Tailwind, but it Tailwind came with nothing, and then you just made your own plug ins at the end of the day. So their their examples is, like, they're saying m dash whatever, and then you you write your own resolver, and that will resolve to margin

Scott Tolinski

whatever dash p x. So you can make your own system. And the power of that is that anyone can publish their own preset, which is essentially their own theme for this type of thing. And because of that, it's it's like you're getting to use the same techniques but different themes.

Scott Tolinski

So you don't have to create it yourself. Like, here's a Tailwind CSS and Windy CSS compatible preset. So you could use UNO, but still use the Tailwind, like, DSL language that you've, like, come to, understand.

Wes Bos

Wes, we're gonna have Antfue on the podcast. Pretty excited about that, so we'll, have to get his thoughts on this. Yes. Absolutely. About utility sprinkles,

Scott Tolinski

because I think this is kinda what we're doing in the syntax website. It is. We mostly use Scott CSS, but a lot of times, it does make sense to use utility. Right? Yeah. And and that's kind of largely my viewpoint on it. I think sometimes when I speak about utility based CSS, people get the wrong opinion that I'm anti utility based CSS or something. And that's not the case. I love utility based CSS. I just don't write all my styles with utilities. I use them for utilities, which is kind of what they were used before we all started using a lot of utilities. You use them for Sanity. Right? So in my mind, you have your your system, which is largely composed through CSS variables.

Scott Tolinski

You have your components, which is scoping your CSS, and then you have your utilities. We talked a little bit about, like, a pill. That might be not considered a Sanity. But what could be considered Sanity is a class called grid.

Scott Tolinski

And that grid class allows you to not just it's not just applying a display grid on the thing. It could be applying your default grid, and it's just Scott grid. And it's your default grid. It's not anybody else's default grid. And the reason why I like this utility sprinkles approach is because the utilities that you end up having, they can be a system that you're used to. They can be the same thing on every project, but the internal CSS that's attached to those utilities can change. Like, if I want the default grid for the syntax site to be always 3 columns and whatever, and anytime I apply dot grid, it's like that. Or anytime I apply dot layout, it does this or that. But then on another site, I want that grid to be slightly different. You can take those with you, modify the CS inside of them, then you have utilities for when you want a layout or when you want a a grid. But it's not somebody else's predefined thing.

Scott Tolinski

And not only that, if I want a grid that's x amount of columns by x I don't have to bring in other classes. I just get to use this is my grid. You know? And I'll I'll tell you. The the 1st utility classes I added to the syntax website was

Wes Bos

text classes because Mhmm. We have we have variables for all of the things, and we have all of our typography JS kinda preset as well. Right? We we globally define what h one through h six looks like. We define what text looks like. Right? All of those situations.

Wes Bos

But there are many use cases where we want to make text slightly larger or smaller, and I was finding it to be a bit of a pain to have to write an h three tag, then go down Yeah. Open up some style tags able. Select the h three tag, and then say font size Yarn dash text dash dash whatever. You know? So we just made a whole bunch of utility classes, text dash, extra small, small, base, medium, large, x large, double XL, etcetera, Text left Yeah. Text center, text right, text justify, text start, text end, these are all just nice little helper classes you can pop on any text that you're writing, and there's no need to select it or or even open style tags. Because there's a lot of components we have that don't even have style tags in them. It's simply just markup.

Scott Tolinski

Yeah. Totally. Alright. So the last thing here is how does CSS variables come into play? You know, some systems are entirely variable Bos. Open props, which is open hyphen props Scott style from Adam Argyle is a it's an entirely CSS variable based system.

Scott Tolinski

And other times, you're using a system as a design token. Now design token is a deep topic. I'm just going to say a design token, generally, at a wide view design token, folks, is, like, these are the variables that your application's using for the system. Right? Your you could think your colors, your primary, those types of things. The variables end up being like, even, like, the global variables. The variables of the system are your design tokens.

Scott Tolinski

High Vercel, font sizes, colors, light, dark. Anytime you're having, like, things that are like, this is how your application can be. These are the the constraints of your CSS.

Scott Tolinski

They go inside of variables, and then you're able to use those variables. I had a good friend of mine who worked at Google who said his rule for CSS variables is never have font sizes or colors ever defined in your CSS. There were some other things there too, but those were 2 of his big ones JS that they had ESLint rules that if you ever had a font size or a color that was not a variable, that it would fail because there's a system.

Wes Bos

That you're you're sidestepping the system and and putting your own value in there. Interesting.

Wes Bos

A and you wanna change the number of columns or change the number of gaps or Mhmm. If you want to that's not even a a very good example because you could just pass in how many it is. But if it's somehow computed, right, like, you have a base size and the rest of them are calced off of that, it often makes sense to put your arguments for your CSS of your component into a CSS variable so that you can override what the default arguments are by simply just passing either by passing in a ESLint style property or by having a Sanity class of commonly used things that will change the variable, which is what we use with our text. It's simply just text dash s m will just change the variable to

Scott Tolinski

a specific value. Yeah. You can think of them sometimes as as, like, props for your components with your variables.

Scott Tolinski

Cool. Well, that's all I have. This has been a very tasty sized hasty.

Scott Tolinski

Yeah.

Scott Tolinski

Probably could've probably could've squeezed the whole shot of this, but you're welcome. Little extra for you today. Yeah. I and you know what? I I love this kind of stuff, so I could go all day. So, we will have to stop. If you have any more thoughts or questions or different approaches that we did not cover, leave a comment down below. And I'm talking about on YouTube, folks, youtube.comforward/addsyntaxfm.

Scott Tolinski

That's the best place to let us know what you thought of the episode or or even, you know, give us some ideas or things that we didn't think about or cover in the episode. So, yeah, check it out, us on YouTube, all that good stuff. Let us know what you think. If you have a different approach or even a different, library or something that we didn't cover here, would love to hear about it. Alright. Thanks, everybody, for tuning in. We will catch you later.

Share