April 15th, 2024 × #CSS#WebDev#Frontend
CSS Is Getting Mixins + Functions
Scott and Wes discuss the CSS proposal for mixins and functions being added to the language. This will allow writing cleaner, more reusable code directly in CSS instead of needing a preprocessor.
- Scott and Wes introduce topic of mixins and functions coming to CSS
- Discussion of caching issues on Syntax.fm site
- Overview of mixins and functions being added to CSS
- Discussion that you can accomplish this in other ways but mixins and functions will help clean up code
- Deep dive into functions - custom functions can return single values
- Mixins can return multiple property values/entire rulesets
- Logic like loops and conditional statements needed in mixins/functions
Transcript
Scott Tolinski
Welcome to Syntax on this Monday hasty treat. We're gonna be talking about mixins and functions in CSS. That's right. There is a new proposal for mixins and functions to be coming to CSS just like we did in many of the CSS preprocessors that's going to lead to an explosion of new ideas in CSS.
Scott and Wes introduce topic of mixins and functions coming to CSS
Wes Bos
Hey. I am super stoked about this. It seems like CSS is working on a whole bunch of really interesting things in this.
Wes Bos
Mix ins and functions proposal was accepted, which means that it's now in the drafting stage to figure out what does it actually look like before it gets implemented in the browsers. But that means that we're gonna get it. You know? I'm pretty excited about it, and we're gonna talk today about what do they do, what are they useful for,
Scott Tolinski
what are the ideas behind it, and, just kinda what to look forward to. Yeah. Totally. And one of the reasons why I'm confident that we're we're gonna get it, right, is that Miriam Suzanne is behind this who, you know, core contributor to SAS, but she's also the one who took the reins on container queries. And, like, that was something we felt like we were never going to get. And churn up Yeah. With with her her push, those those ended up arriving in the, CSS platform. And, man, we're using them today.
Scott Tolinski
And in addition to that, hey, stuff that we're using today, we're using Sanity. We're using Sentry on our site. In fact, CJ, just the other day, he posted, this morning that he was getting a lot of alerts for some errors and used our Sentry to track down and that it was hey. What? Guess what? A caching issue. What was it? Looked. Oh, of course. It was a caching issue.
Scott Tolinski
So he was seeing some some HTML that Wes, trying to load some data that wasn't there. The data wasn't there because the old data was cached in our Redis. He dumped the cache, fixed the bugs. Well, at least fix the errors from happening. Now we just need to take care of the situations in which those errors would not be happening. Because what? Guess what? If TypeScript thinks that that data JS gonna be there, but the data's cached as an old version that doesn't have that same correct data structure, TypeScript's not gonna save you there. And so that was a a neat little one that TypeScript wouldn't caught Interesting. But Sanity caught for us. And, all we had to do was dump the Redis cache. So Oh. But Yeah. Maybe maybe we need to, like, dump it on every deploy or make the cache
Wes Bos
deploy specific.
Discussion of caching issues on Syntax.fm site
Scott Tolinski
Yeah. Or we could just have a button that you click whenever there's a problem.
Wes Bos
The the current the current way. It's too late. That way. You could you have to click this too late.
Wes Bos
Joking.
Scott Tolinski
So if you wanna, get this kinda error handling in your site, have it on our 2nd century.i0forward / syntax.
Scott Tolinski
Sign up and get 2 months for free. Yeah. Wes, I'm I'm certainly not suggesting that we do it the way we currently do it, which is not working clear clearly.
Wes Bos
A physical button on the wall that we hit. Yeah.
Scott Tolinski
Smash. Dump that cache.
Overview of mixins and functions being added to CSS
Wes Bos
Alright. Well, let's talk about functions and mixins being added to CSS. So we've had CSS custom properties, CSS variables for quite a while Node. And it feels like in the last couple Yarn, now that they're supported in every browser, now that everybody's starting to use them, we're seeing some really, like, dynamic stuff, being able to write less code, being able to write more flexible code, and they're awesome.
Wes Bos
However, there still JS. Like, we did an entire show on, like, can you is SAS dead? Can you dump SAS? And 2 of the like, pretty much every feature of Bos, we were saying, yeah. Yeah. Yeah. Yeah. Yeah.
Wes Bos
But the the big one was the ability to have custom functions and custom mix ins. And while you can do some of this stuff with variables and and make your selectors a little bit more dynamic.
Wes Bos
There still are a lot of use cases where either the code you write is gonna be funky or you're gonna run into weird scoping issues or you you're not able to loop into it. So functions and mix ins being added to CSS is going to solve all those problems. And we're gonna talk about Scott of, like, why might you wanna use this? What are the actual use cases for it? If
Scott Tolinski
you just go down the list of, like, Sass features that are in CSS, so just looking at the Sass features, variables. Okay. We got it. Nesting Yeah. We got it. Partials, we still don't have. That would be neat to be able to import in a way that was not detrimental to performance. Right? But you'd still obviously kinda need Node compiler for that. There's no way around that.
Scott Tolinski
Modules, I guess that's the same thing. But we do have CSS modules in JavaScript, mixins, and functions, essentially. Now functions are often used or operators and loops are are still also things. But, you know, mixins and functions are are are 2 types of things that I I use frequently for both functions that I wrote, mixins that I wrote, but also ones that you imported from third parties or functions that you use that were baked Node Sass that could now be baked into whatever CSS library you're using. Maybe there's like a a default CSS functions library that you're using that includes things like lighten or saturate or or those types of things that we got to use in Sass.
Scott Tolinski
And well, that'd be it'd be fun to have them, honestly.
Scott Tolinski
So, you know, a lot of these things can be accomplished different ways, you know, maybe with more code, maybe with, I don't know, actually using a CSS preprocess or all kinds of maybe even just JavaScript.
Scott Tolinski
And I know that's gonna be some of the comments because even when we did the has video, people were like, you can do this other ways.
Discussion that you can accomplish this in other ways but mixins and functions will help clean up code
Scott Tolinski
And sure enough. Yeah. You can do these things many times other ways. But a lot of times, this is saving us, it's saving us code. It's allowing us to write it in a more readable way, a more organized way, a more shareable way. And largely, it's just going to expand the ability for us to work within CSS as a platform.
Wes Bos
Totally. Totally. And, like, yeah, like, you shouldn't have to pre generate every possible option that is out there. Even if we have the tools to figure out what are the possible selectors that we need to generate and and how can we use them together, You shouldn't have to do that JS well as there's some some benefits to be gained here. So let's talk about it. Functions and mix ins, they are being grouped into the same proposal, and both of them are going to have names or identifiers.
Wes Bos
And both of them are gonna have arguments or parameters, so you will be able to do things like fancy button and pass in, what color you want it to be, what the radius you want it to be, and then you can get a bunch of CSS back. The difference between functions and mixins is that CSS functions are going to be used to calculate a single value, whereas mixins are being used to group together and apply a bunch of CSS to a specific selector. So, again, a function can be used to like in JavaScript or literally any programming language, a function can be used to tuck away complexity and make something a little bit more dynamic, whereas a a mix in will also be able to do that, but it will return a bunch of CSS media queries, container queries, internal logic that can then be directly applied with they're they're proposing an apply.
Wes Bos
But, again, all of the syntax is sort of up in the air right Node, and it's still being discussed. So don't well, maybe do.
Wes Bos
Maybe do get get hung up on this syntax right now because all too often, we hear people start whining about syntax and why did they do it this way, and this is not as good as they want it. Now's the time. If you really care about this type of stuff, if you care about how it's going to look and and hopefully some really smart people too because these hard conversations need to be had now before the the draft, and the syntax is finalized.
Scott Tolinski
Yeah. In in that same regard, don't be rude about it. You Node, understand what you're arguing for and why, and take some time to have a thoughtful reason why you might want something. Don't just say Yeah. This and tech sucks. Right? Often, I I like it when,
Wes Bos
like, regular people get involved in the standards process because often they'll ask questions like, why is it done this way? Like Yep. I find myself doing that with a lot of the React server component stuff. It's like, I know there is probably some sort of complex reason behind all of this, But, a, I don't care.
Wes Bos
And, b, why can't it be as easy as as this? You know? Yeah. Like, all of the complexity and limitations and all of that aside, I just want it to work like this. And that's why it's important to sort of get get involved because maybe we've often seen that we're like, okay, well, same with, like, the nesting Wes had that we had, like, the weird you have to do the ampersand.
Wes Bos
And, like, everybody's like, I don't want the ampersand. Like, you know, like, just make it make it the other way. And then they're like, well, you can't really do that. You're gonna break CSS. Then they're like, well, actually, we found a way that we can we can make that work, so it's kind of important.
Deep dive into functions - custom functions can return single values
Scott Tolinski
Yeah. Totally. And if you're thinking about, like, okay. So let's get into functions first. Right? Let's deep dive into functions Node that we kinda have a handle on these.
Scott Tolinski
I think if you think about it, you might be wondering about, like, is this too much for CSS? But we already have a number of functions in CSS already, and we're getting new functions all the time.
Scott Tolinski
This is gonna essentially just allow you to define your own custom functions.
Scott Tolinski
Like, what kind of functions do we have? We have calc, min max. We have, Clamp.
Scott Tolinski
Clamp, color mix.
Wes Bos
Color yeah. Or or color mix didn't know. Color mix got nixed. Color contrast might mix
Scott Tolinski
Contrast color is the new Con I don't know. Color adds
Wes Bos
but that's that's the other thing is that we do have these functions built in, and then sometimes you look at them and you go, like, it seems like a lot of work to still do this. The mixing colors syntax, not very good. Right? You have to do from the hex code, then you get the r, the g, the b, or the h, the s, and the l, and then you can recreate a color with it. What about darken, lighten? You know? How about that would be nice. And there's there's a line that needs to be drawn somewhere between, like like, someone's gonna give you lighten and darken functions. Alright. They built it in, and someone will say, yeah. You know what? I don't like that algorithm for lighting and darkening because it doesn't look as good. I'd rather do it on this curve of light lightning and darkening. So
Scott Tolinski
just even functions. We can make our own. Yeah. Or even like, hey. This function that is built in is perhaps too general, And I'm having to put in all these options, but maybe we want our functions to be more specific to the code that we're writing, the project we're writing. Like, I want this to lighten to the degree in which I wanted to lighten every time. Or I want this to apply a transformation that's only applicable to my my project itself rather than, you know, the global. And so what you have there is you have the ability to write your own essentially bespoke custom functions or again, library authors. This is a huge opportunity to start thinking about, alright. Like, what kind of functions did we have in stylus? Or what were those, like, what was the I know Compass was the one for Sass, but what was the one for stylus that was, like, the addition to stylus that do you remember?
Wes Bos
No. I I was extremely heavy stylist user, and I never used I it was all built in as as far as I remember.
Scott Tolinski
There was an additional library to stylus that I did probably do a video on at one point on level up tutorials.
Scott Tolinski
And, but just like, what are these additional functions that exist out there? Or even, like I Node, like, breakpoint stuff was, like, really good within function. So, what kind of things might you think about if you are a library author or or just a developer who you might wanna get into functions?
Wes Bos
Mhmm. So some other use cases Yarn, like, a theme function would be really cool if you wanna be able to pull specific values from your user's theme or if you wanna do something conditionally based on a user's theme. Like, you could have a light and dark theme, but then you could also have a, a dense mode or a, like, a, like, a Scott like, that's one thing I wish Notion had is there's so much padding in Notion. It drives you crazy. It's like, well, I I I want to be able to make this window smaller and not give up half of it to padding. So I wish that there was, like, a dense mode, but I also want dark mode, you know, like, to be able to to mix those 2 together.
Wes Bos
And that's really hard because you have to use variables, and and then you have all these weird weird edge cases, and things are scoped a little bit funny, and a theme function would be really nice. I I can think of the syntax website right now JS sometimes we don't want to get the inherited variable. We just wanna simply grab the the actual theme value there, and you could pass in arguments of which theme value you want. Imagine being able to say, like, theme background instead of dash dash, I I forget what it's called, or dynamic values.
Wes Bos
In the syntax website right now, we have a, like, a background grit texture that's programmatically generated, and we have a light mode and dark mode version of that. Right? And we have 2 variables, the light mode and the dark mode, and then we have another variable that's just grit texture, And the the value of that changes depending on if you're in light or dark mode. So wouldn't it be cool if you just have a nice function called BG texture, and it can return that value or complex calculations? Often Wes you're using clamp min max calculations, container crewer units based on the size of the container or based on the size of immediate query converting pixels to REMS or MS to REMS. All of that stuff is sometimes like, holy, this is very complex.
Wes Bos
Like any function, it's nice to tuck it away into its own function Wes you can simply just use it and pass in the 1 or 2 dynamic bits that you want.
Scott Tolinski
Yep. You could even do some, like, fun things. Random values. Hey. I mean, there there's some interesting things or even, like, default padding or, you know, just you could pass in something and and it becomes context aware. Right? Because, again, you have these parameters.
Scott Tolinski
Utility functions like we mentioned. You'd lighten, darken, you know, Sanity. Those types of things Wes, again, you're getting more control over how you would do that application, and you can write the underlying implementation of that to have it fit your needs. But also, like, hey. You could write your own contrast color function to have that available to you while we're waiting it for it in the browser if it comes or doesn't come. Right? I think it what it does is it opens up a world for us in CSS here where we're not waiting for the browsers to implement
Wes Bos
all of these different functions. Right? Yeah. Yeah. I'm I'm working on a website right now, and I have all of these different background colors. And for each of the background colors, I have an associated text color that looks good on top of that. And and what I need to do is a section by section, I set the text color and the background color.
Wes Bos
And then I have buttons that are also that color, and they need to inherit. But if that button is a different one, then I need to set the scope of the the values on that button instead of the the parent. Wouldn't it be nice to just say especially when Wes we get style queries, being added to the language as Wes, wouldn't it be nice to say if it's pink, then the text is going to be this specific white?
Scott Tolinski
Yeah. Right. Again, those are finely tuned to whatever you're working on. Right? That's not something that would ever get added to CSS. It make Yeah. If text is pink, make white. You know?
Wes Bos
So that is CSS functions being able to take in some values put some logic inside of that and return a specific value a mix in would do the same, but instead it will return a bunch of property values. So it could return you could have at mix in cool button, then it would return the border radius, the background color, some complex text shadow, a set of backgrounds, but it could also include container queries, support queries, media queries, all of that stuff inside of it. And very similar to what a a class is like. You're probably saying, like, that's that's a class. Isn't it, Scott? Yeah. Yeah. Well, it's it's it's not class because
Mixins can return multiple property values/entire rulesets
Scott Tolinski
it takes parameters.
Scott Tolinski
Like Yes. The way you'd have to do that with a class is that you'd have to have every class with a hyphen parameter that you could possibly think of. And largely, this is how tailwind works. Right? Like, you have the class hyphen and then some properties. Right? And this is something you could do with mixins because you wouldn't have to have all of those classes generated there. Now I know Tailwind has like the just in time stuff, but, like, you'd be able to have this without any of that extra stuff.
Scott Tolinski
Because, again, it's accepting some parameters and now putting a whole bunch of classes. To me, this is like the promised land for really concise CSS, really team CSS. You write your mix ins. You write them so they're flexible for your needs. You drop them in. I can, like, think of just a ton of ways that you know, I've written classes before, like grid classes or something like that. You could write a host of grid classes that could attach to different grid columns or rows without them having to, again, have all of those classes prewritten in your CSS.
Wes Bos
Yeah. You you don't have to generate them, and they can be runtime dynamic.
Wes Bos
Meaning that, like, I I think the tailwind folks are really gonna like this type of thing because the the killer feature in tailwind is the arbitrary value syntax where you put square brackets after it Mhmm. And then you pass whatever you want. And, like, if if tailwind doesn't have what you want, then you can just say, alright. Well, my background color isn't set or I want it to be 24 pixels because of whatever reason, you can use the arbitrary value syntax. However, that is still dynamic. It's not generated at build time. So if there are any CSS variables that need to be used in there or if there is any logic that needs to be set inside of that. It's not just explicit static arbitrary value. Yeah. It could be dynamic based on other variables that are on the page.
Scott Tolinski
Default values, all kinds of stuff being 1. As part of the spec as well. Yeah. Yep. Yeah. I I I do see, like, I see, like, the next generation or even the next generation of tailwind, like, using this stuff explicitly behind the scenes. Because it it does make so much sense to be able to apply all kinds of stuff with these defaults to just have it drop in your CSS. Yeah. Like, if you think about the tailwind colors, there's,
Wes Bos
what, like, 11 different colors and or 14 different colors and 11 different variations. Like, it's 240 whatever colors that are available, and then you wanna be able to do different opacities for each of them. So forward slash 10 forward slash 15.
Wes Bos
So that's the millions of different combinations. And and obviously those are are generated on on build timing. You only take what you need. But
Scott Tolinski
imagine, again, it could just be done in the browser without any sort of, build tool. Yeah. Imagine this Node. Remember when we used to use in, I remember used to use in stylus and sass was just to make a triangle and have it be, like, dynamic Yeah. That was huge. Yes. Just needing something like that, because, again, you could have a class that's triangle that gives you a triangle, but you can't have one that makes it totally
Wes Bos
dynamic based on what you need out of it. So, you know, is it useful for that? Yeah. You could have a triangle mix in or you pass in a color, and you could pass in where you want it to be, you know, top right bottom left, and then it will generate all of the CSS that is needed for that. And it it's extremely complex.
Scott Tolinski
Yeah. Yeah. Super duper.
Wes Bos
Fluid typography, that's another big one. I've been a huge fan of the container query units, and that is where you set a container on a element and then you get these c q w c q h like you get width and height of your container query and then you can use that to dynamically size things inside of it like text.
Wes Bos
So fluid typography, it's still a bit of a pain. You still have to, like, test it and whatnot. And and then also if you want it to be different at different breakpoints or different container query breakpoints, like, if you wanted a medium and a large size container, then you're getting into to a lot of CSS. Again, sticking that all into a mix in was would be really nice.
Scott Tolinski
Yeah. Totally.
Scott Tolinski
It's funny, Wes. I'm looking I'm just, like, googling around to try to find some of the old mix ins that I used to use in stylus, and my my videos keep popping up from 2013. I clicked that one. I was like, oh, man.
Scott Tolinski
Oh, man. My old office, my old, my old vibes, very weird to see that. That's that's great. Let's talk about logic because
Wes Bos
inside of both mix ins and functions, we are going to need logic. Right? And Yep. You can love it or not, but CSS is a programming language JS as far as I'm concerned.
Logic like loops and conditional statements needed in mixins/functions
Wes Bos
It's very declarative, meaning that there are no really if statements or looping, but we we do for this, we will need to add looping to the language, right, because there is not really a great way. You can get around looping a lot of times with just dynamic variables, but there are lots of use cases where you simply I just need a loop here. And if you either have to reach for something like like Sass or a preprocessor or you just rewrite a whole bunch of classes ahead of time. But we do have a lot of conditional logic already. Right? Like, we have media queries.
Wes Bos
We have CSS is, has, and where Yeah. Which is a lot of it's kinda if statements. Right? Yeah. That's the query thing about that way. Yeah. And, like, style queries is going to allow us to say if it is red, then do this. You'll be able to query things based on their color or based on their size or based on their width. So you can say if it has this specific style applied to it, then apply these following styles, which I think is pretty nifty. And then what else Wes have? Supports, container queries
Scott Tolinski
and style queries, I think, will blow this wide open because style queries are really just, like, pretty explicitly conditional statements. Right? Yeah. You're saying if this value is this, then therefore apply the CSS. Hey. That's an if statement. So for me, that that is the one where yeah. I would,
Wes Bos
that kinda blows us wide open to me. It it is because I'm trying to think, like like, what else? If we get mix ins, we get functions, and we get
Scott Tolinski
style queries, which is already approved, it's being implemented. Yep. Like, what else? Style queries, you can even look at the value of a variable. It doesn't have to be even, like, a CSS property. You can look at the value of a variable, which can be set to anything.
Scott Tolinski
Like, that really blows it blows it wide open. Yeah. Because you could stick anything in a variable. Right. You can stick anything in a variable. Especially with the new app property too, you could get really, really dialing with the the type of a variable.
Wes Bos
So That's pretty cool. Like, I'm trying to think, like, what else like, people have wanted to put multiple properties into a single variable. Right? Like, so if you wanted to have dash dash button and you could put 6 or 7 styles in that, but
Scott Tolinski
that's what mixins are. Right? So, like, that's one thing that isn't needed. Yeah. And then hey. Just update on style queries. They have partial support in Chrome and Safari already. No support whatsoever in Firefox.
Scott Tolinski
So, partial support in Chrome is that you can use style queries with CSS variables.
Scott Tolinski
Yeah. I know what it is in Safari, but working with CSS custom properties. Okay. It looks like it's the same for Safari.
Scott Tolinski
So it it also I think there'd be yeah. Yeah. There's there's no movement on it in Firefox. Who knows where that's at? But, yeah, that's a future I wanna live in for sure.
Wes Bos
Yeah. Maybe, like like, objects. Like, what if you had, like, a a variable for a theme? So dash dash theme, and the spec intentionally allows anything to go inside of a CSS variable. So it it's not crazy for us to be able to do that. Like, maybe you could have a dash dash theme, and inside of that have subvariables, you know, background, foreground, border.
Scott Tolinski
Oh my gosh. Red Green Blue. Imagine, this world. I'm I mean, you can have multiple parameters and mix ins and stuff too. So, man, it's, it's very, very exciting here. And, if you wanna follow along, we'll have all the links for you in the show notes here. Again, contribute again, but be kind and and considerate when you're contributing and make sure that you're being helpful and productive. But I think they wanna know how people are thinking about this and how it might affect what they're writing in CSS.
Scott Tolinski
Don't just pop in there and be like, can't this just be a class? Don't do that.
Scott Tolinski
Yeah.
Wes Bos
Awesome. Alright. Thanks for tuning in. Peace.