Noel: Hey, and welcome to PodRocket. I'm Noel. And joining me once again today is Adam Argyle. Adam is CSS dev advocate on the Chrome team, host of the CSS podcast, and has been working on the GUI Challenges podcast, video series, something. How's it going, Adam? Adam Argyle: Hey. It's really good. Thanks for the intro. Noel: Of course, of course. Yeah. Yeah, there's a whole bunch we can talk about. We were just talking about how much we have to try to get through in an hour here. So yeah, let's jump right in. You recently spoke. It was several months ago, at this point, at the Google IO State of CSS, 2022. Any highlights there or anything you want to cover or expand upon a little bit? Adam Argyle: Whew. I don't know. It's so funny. You get to go to IO. You see this 15-minute video where I jam-pack a whole bunch of stuff into 15. I whittled that down from an hour, and I whittled it down from... I think I originally wanted to talk about 25 things or something. I was like, "I can get 25 things in in 20 minutes." And then it was like, no. No, you can't. So the blog post ends up being this place where that was what I truly wanted to talk about. But then the Google IO talk is like a wham-bam, thank you, ma'am intro to everything, but yeah. Noel: Yes, intro to everything is... yeah, is quite the sell there. Yeah. So I guess, I don't know. Are there any super high-level highlights we could start with and then dig in a little bit? Adam Argyle: I'm mostly just pumped that everyone received all that information so well. Things I spent 45 seconds on are really heavy. Cascade Layers is a good example. I gave a brief intro, said, "Here's one use case it's good at, but it's got way more than that." And then I also appreciated a lot of people recognized how cool Interop 2022 is. It is nice that the browsers are hacking together to make something stable. It's not like we just want new hotness that's all wiggly and wobbly. We want new hotness that deploys stable across. Right? We want that grid experience. Right? When Grid launched, you're like, "Dang! Grid is just everywhere now, and it's ready to go." So yeah, it's cool. Noel: Yeah, yeah. Yeah. The ubiquity there is cool. I guess maybe to step on that note to set this up a little bit, can you talk about your current role as a CSS dev advocate and where you sit on the Chrome scene, maybe for listeners who haven't been in before, and then how that plays into the way you look at interoperability. Adam Argyle: Awesome. Yeah, that totally makes sense. Okay. So I'm sitting between PMs that manage actual features on Chrome, so that's like automatic dark mode and all sorts of things that are coming out, and even just the rendering team and the touch and interaction team. So there's a team that does all the scroll, all the scroll snap animations and the frame rate of those animations, and stuff like that. So then, there's another team that's all about rendering and layout and getting the performance of just rendering a whole page done. And then I have my own managers that want me to be doing DevRel things. Right? And then I have the CSS working group, which is a place where I go contribute to agnostic to Google's endeavors. This is just pure CSS and wanting to do things well there. Adam Argyle: And then the most important part to me is listening to everyone else, having conversations with people in the hallway, having conversations with my friends, having conversations on calls like this, just knowing what it is people are actually building. What are you using it for? What are the bugs? What sucks? How do I make that all better? Adam Argyle: And yeah, in the middle of all this, I will soak it all in and then write an article or go advocate for some new feature or go test some new feature. That's one of my favorite things to do. They're like, "Hey Adam, we think this feature's ready." And I'm like, "Oh, do yeah? Let me go ahead and build a couple of demos and just show you how it's not yet." And that can be fun. Or just building demos that showcase all of the difficulties of something, like Scroll Snap is one like, I'm involved in these new scroll snap APIs that are coming out. Well, they're not coming out anyway. I'm still specing them. But anyway, I have to go build all these Scroll Snap demos that then show the pain points. And so it's fun to just do all that. It's a mini hat job. I also record videos and audio, and so I'm a video editor, and I'm an audio editor. I do so many things. Noel: Yeah. Nice, nice. Very cool. What efforts, or I guess, how does Google set up itself so it can work with other browsers to provide this compatibility across the browsers and ubiquity in APIs and stuff? How do they push that lever? Adam Argyle: Yeah. There's a team that has run surveys for developers. So the developers report, saying it's really difficult to do something cross-browser. And so that's been so consistent for so long that now it's bubbled up into a team's effort to make that better. And they'll go back to Google or Chrome, and they'll be like, "Hey, Chrome, people are struggling to build things across browser. Maybe you have the feature, maybe you don't. It makes it really hard for someone to build these modern experiences if it's not everywhere." And so efforts are being done to go identify what all these things are to query developers, to figure out and prioritize what these things are. All in all, Chrome's interested in you building things on the web. And if you're struggling with that, and if cross-browser is an issue, we even fund other browsers getting features and stuff like that, or we'll help assist other browsers level up so that we can all rise together. Noel: Yeah. Nice, nice. Nice. I guess, are there any good recent examples of that we could pull in? Adam Argyle: Yeah. Last year was the 2021 compatibility effort, and the compatibility efforts were around things like... Flex is a very complex layout engine, and so to make that work, there's... well, I guess, long story short is, it was so complex that it had a lot of edge cases that weren't compatible across browsers, and it might have been even missing spec text or something. And so we'll have an engineer go in there trying to fix all their Flex bugs. Here's a funny thing. You think of Chrome. It's like thi ... well, maybe you don't. I don't know. But it's this really solid piece of software. Surely they're not shipping bugs. This is Google Chrome. This is the top engine. No. They're shipping bugs all the time. It's just like the amount of code that's shipped is so humongous, you don't see it. Adam Argyle: And Flex had hundreds of bugs on it at one point. So did Grid. And so Chrome, in an effort to lower its own bug count and make it work better consistently across all the browsers, they write their tests, and then they fix their bugs against those tests. So by writing tests for the web platform tests, the WPTs, other browsers get compared against those same tests, and we can all see our score against that. And that score is what started to roll into that Interrupt 2022 effort. And so a couple of years ago, yeah, that 2021 compat was all about Flex, Grid. Adam Argyle: I think I go over this in the video too, but it transforms and some other things. So they're normalizing a baseline. And the Interrupt 2022 is... developers want these features from CSS. How about we just agree what we're going to hack on this year? And they set up meetings, and they set up these little committees, and they discussed what to build. And they all just started hack... the list is huge. I was like, "Y'all were really ambitious. You could have just said, 'We'll, do these three things this year.'" But they're like, "Here's 10." Well, awesome. I will use all these things. Noel: Nice. Nice. Who is involved in that decision-making process outside of Google? Who are the representatives there? Adam Argyle: Yeah. So let's see. You have Safari and Firefox are sitting in that meeting as well. I don't know if other browsers are too, but these are the primary contributors to the web platform tests. And the web platform tests were ultimately what you had to pass to get this new Interrupt. So Interrupt 22 is very literally a set of tests that you're either passing or not, and so that's how it gets segmented and gets measured. Noel: Gotcha. Gotcha. So are those tests then coming out of the spec? I guess, what is the journey like from okay, we have the spec, this is how things should work? This is what we generally want to do. These APIs make sense. To then getting the web platform tests defined and figured out, what does that middle piece look like? Adam Argyle: Yeah. I think it's pretty normal where you'll have a document that says you have a feature to build in your software. You might go write some tests, so it's likely you'll have some amount of TDD. You're not in full TDD. There's no spec that all of a sudden had... no spec lands with a complete set of tests. The tests are written by the engineers building the feature out of their own necessity to test the things they're seeing. And so the completion... and this is pretty typical. Right? You're like, "Oh, I made a function. It accepts this thing. And you passed the thing because I wrote both sides of it." So that there can be a little self-fulfilling in that way, but it does still get to a stable set that then other browsers can at least start building on it. So then you have multiple contributors into these platform tests. Adam Argyle: The feature goes into a prototype stage where browsers are like, "Hey, we have it behind a flag. You can go try it out." So people go try it out. These tests are getting built more and more as people find edge cases. Browsers are also working on the feature more, seeing that they're failing more tests. And eventually, it gets into a decently hardened state. But to be honest, just like any test scenario, you just almost seem to never have enough time to write enough tests. It's just a really complex thing, so that's what happens, though. Adam Argyle: The spec text gets written. Oftentimes in that prototype stage where the web platform tests are getting rewritten or more tests, they'll give info back to the spec. So it'll be like, "Hey spec, we noticed that you missed this thing." The Flex compatibility efforts of a couple of years ago really started to get really fine details about what does Flex direction do when the language is right to left and the flex columns are set to this? And you're just like, "Oh yeah, row reverse." Row reversed right to left with some logical properties. You're like, "Oh, wow! That's my head spinning. And so yeah, just getting that all. So yeah, it cycles like that. Hopefully, that's a good answer. Noel: No, I think that makes sense. Yeah. I can't count the number of times where you get the feature request just in general software dev like you were saying. You go in, and you start working on it. Then you're writing it or writing the test for it. You're like, "Oh, wait, what about all of these permutations we hadn't ever considered?" So I think that makes sense. I've just only ever experienced that personally on an internal team working on a thing, or even like an open source project that's a little bit more controlled. I feel like doing it on something like web APIs just sounds like it'd be so much more, I don't know, involved. And every time, we're like, "Oh, the spec doesn't cover this." Well, going back and getting that well-defined, is that a drag? Is that a lot of work sometimes, or is it usually pretty snappy? Adam Argyle: Hmm. I mean, I think the short answer is yes. Anytime you think you're done with something, and then someone's like, "You're not," and you're like, "Okay, I'll do one of these." And then after you get 10 of those, you're like, "Now this is getting less fun." But just like normal, when something's done, it's done. And it got vetted by so many different brains that you can feel really confident about it. And it's like, "Oh, this did. This just went from inception to a hardened idea." And it just took some time. Right? You got to roll it, spin it up, let that thing tumble. Yeah. Noel: I mean, I think that's what we would want too. We want the web, the things that are driving the web, to be pretty hardened ideas. Adam Argyle: Yes. I agree. Yeah. Noel: Yeah. That makes sense. Adam Argyle: The funny side note is the web platform tests are almost exclusively HTML files, and that is just not how anybody writes TDD or how they think about it. When you're writing tests in your mind, at least for me, almost entirely, I'm like, "JavaScript, JavaScript, Mocks, JavaScript, Spies." All these things went, "JavaScript, JavaScript, JavaScript." And then you get into the web platform test. You're like, "They're just running documents?" And you're like, "Wow! That's cool." Okay. Anyway. Noel: Yeah. Yeah. A very true test, I guess, in that regard then. Yeah, that's awesome. Yeah. Very cool. I guess, yeah. We talked about the Flex and Grid compatibility and stuff. Is there anything else that's in that vein before we shift gears into some of the newer stuff that's coming down that might be exciting? Adam Argyle: That's exciting? I mean, a lot of the compatibility stuff was boring, to be honest. They were a lot of scenarios that most people weren't hitting. They were typography fixes for things that most people weren't experiencing because they might be in a different language. Now, the compatibility stuff wasn't nearly as exciting as Interrupt 2022, which is like Christmas. It's just like ching, ching, ching. They're like, "Wow!" Noel: Right. Yeah. So what are you most excited about as far as new stuff goes? Adam Argyle: Ooh, this is a tough one. I think color, and has, and scope. At scope is really going to help people battle less of the cascade. We could have this concept of CSS modules right there. You've got the donut scope as well. So scope, meaning it won't trickle down forever in your components. You can set an end to where a custom property is. You're like, "Here's a custom property for my component." And it ends at the end of this component at this part of the tree. And that is really cool stuff. Adam Argyle: Color, though, is amazing. I learn more about color all the time, and it becomes... yeah, it's one of those specialties, those little niche details. You're like, "Why do the gradients here look so beautiful?" And as you train your eye, you start to see these things more and more. And the web is about to have the most powerful design canvas in the world, and that, to me, gets really exciting. So I'm waiting for design tools to catch up. I'm like, "Hey, design tools, you see all the stuff browser is doing now? Hey, when are you going to give designers the ability to make container queries? Hey, when are you going to give designers the ability to make grads in OKLCH? That'd be really sweet." But, yeah. Noel: Do you think that there's a weird... I guess, with most new features that come to the web in regards to, I don't know, color, or layout, or design, before the tools catch up where the only people that can really use these things are the devs that can do the work manually, do you think there's usually a delay in there where the tools aren't there, so they're getting used in niche instances by devs who cared about this thing? But they're not really being pushed by designers, so we don't see them bubbling up. Adam Argyle: Yeah. I see designers, and they're... It's hard. You have two mainstreams. There's a mainstream developer set where... I mean, this could be your react world where it feels like everyone is there. And designers have another stream where they feel like everyone is in Figma, or everyone is in XD, and everyone is using tokens and the components that they're given there. And so, while they're in those worlds, it does. It takes tastemakers and people looking at the edge to find these new features, to go push for them in their particular tools. So whether it's an IDE to have syntax support for container queries, or if you're in a Figma file, and you're like, "I would really like to make adjustments based on my container," which is how I feel like I'm working, but it's still a little view port-esque. I don't know if I'm totally answering the question, but I think there is usually some back and forth. Yeah. Noel: Yeah. I mean, it was a nebulous question. I just feel like historically, I've always observed when new features come to the web, it's like until those design tools catch up, you're really only seeing them in code pens and stuff. Devs are like, "Look at this cool new thing I can do with web." And it's not really out in the wild. It's not on brand landing pages and stuff like that yet just because it doesn't seem to be in the tool space that the people setting up those really heavily used consumer products are using. So I don't know. I was just curious if you'd seen that pattern as well and if you think there's anything that we could ever do to make that easier. Is there anything we could do to make it so the tooling is easier to keep in line with the spec, the stuff the web is capable of doing? Adam Argyle: Yeah. That's a good point. So it's almost like the more infrastructure you build for your... let's say your web design tool. So you've got all these GUIs that help you build component-based designs. They're going all-in on managing so much stuff for you, simulating container queries maybe, or trying to give you future features early. And then it gets difficult for them as soon as it actually comes out. And now they're like, "Well we have the synthetic one, or now there's the real one. How do we pivot from here to there?" And yeah, sometimes the browser comes out with the feature first, and it takes a while to go back upstream. And sometimes it's design tools that have things first, and it takes a while for those things to go downstream into the browser. Adam Argyle: I think to make things easier is to stay closest to HTML. Every time I choose a framework, I'm able to get in one direction really fast, but another direction, I move further away, which is, yeah, closer to the spec, closer to fresh things that come out. The less tooling I have, the more availability I have to just be nimble and try something new. But that nimbleness comes with the cost of, well, this other app was really sturdy. Maybe it was built in type script, and I have three years' worth of code in there. And well, that's just a mature product, and it's going to be a little hard to move versus something new. Adam Argyle: That is a interesting, though, relationship between new features, getting them into IDEs, getting them into design tools and that cycle. It also is a cool thing for jobs. I think it makes it nice for new tools to come out. I don't know if you remember when Sketch came out. It sounded like Sketch was never going to lose. Every designer was on Sketch thinking it was the bee's knees. And then, all of a sudden, it was like toast one day. Figma came out, and you're like, "Wow! They conquered that, which I thought could be unconquered." I think we'll just keep seeing that. It's almost like a healthy churn as things make bets. They make bet on a certain technology. Sketch made some bets on their document structure that was SVG-based. And yeah, I don't know how to... it's fun, but I don't know how to protect one's self. Noel: It's tricky. It's almost like the tool ties itself to a certain layer of abstraction from the spec. This is how close we are willing to tie ourselves absolutely in a way that is probably going to be irreversible long-term. This is the layer of abstraction at which we jump in. If the demand for that changes, it's easier for the tool to get undermined by something else. Like, "Oh, we want to be at a different layer of abstraction." And it feels like as the web specs become more robust or can do more, or easier to work with, maybe, it's like, "Oh, maybe there is a demand for something that integrates a layer down in abstraction." Adam Argyle: I'm thinking Framer X is a good example where, yeah, they went all-in on a abstraction layer, which was a smart choice. That is the most popular abstraction layer. And then you get a bunch of superpowers because of that, like, "Here, we'll give you code." But yeah, you do. As you invest in one thing, another part of your muscles get weaker, I guess, and stuff. Noel: Yeah, yeah. Which is what we want. Right? If we were all writing C code still, it would be slow sometimes. It's the same story as everything else. We like these layers of abstraction because they help us, but there's definitely an interesting philosophical rut to get into there. Adam Argyle: I agree. Emily: Hey, this is Emily, one of the producers for PodRocket. I'm so glad you're enjoying this episode. You probably hear this from lots of other podcasts, but we really do appreciate our listeners. Without you, there would be no podcasts. And because of that, it would really help if you could follow us on Apple Podcasts so we can continue to bring you conversations with great devs like Evan Hugh and Rich Harris. In return, we'll send you some awesome PodRocket stickers. So check out the show notes on this episode and follow the link to claim your stickers as a small thanks for following us on Apple Podcasts. All right, back to the show. Noel: Yeah. Cool. Anyway, let's come out a little bit. So you said color, you're excited about. You're excited about scoping, like the queries, the selectors to pop in and pop out. What specifically in color, if we can dive in a little bit there, is cool? Why now is the web more powerful in that regard? Adam Argyle: Yeah, there's two main things I think about. Oh, maybe there's three. Everyone in their, well, not everyone, but many people, in their pockets and on their desktops, they have gorgeous displays, and the web can't use the colors. So that's the first one. You're stuck in the same colors that your 20-year-old TV has. And you're like, "Well, now I have a new TV. I'd like to see those colors." And the web can do that in video and images but not with CSS. And so it's going to be nice for us to create gradient and to create shadows, and to create these things in these newer color spaces that are going to give us a lot more depth, a lot more vibrance, a lot more beauty, so it's going to pull out that quality of the display. Adam Argyle: The second thing I really like is the interpolation spaces, so going from one color to the next. We have all these tools now that help us work around RGB where you can... I want to go from red to blue, but I'm going to add a special little stop somewhere in the middle so that it doesn't do its dumb travel. It doesn't travel through the dead space. I'm going to help it work around the dead space. And then, well, in the future, we're going to have these color spaces that just do that for free. They're just built that way. The way they pack the colors is so that the things travel through the vibrant areas if you're going from vibrant to vibrant. So that's another thing. So you have new colors. You have this ability to specify how you want them to transition. So this is almost like an easing curve between color. Ah, it's not the same, but it's similar. Adam Argyle: And the third thing are color functions. So you've got color mixing, which just sounds like a basic thing we should have had a long time ago. Mix red with white. Ah. Then thing number two is color contrast, which is a very magical function, which will take two colors and tell you... well, you take a base color, and you compare it against a sequence of colors, and it will find the one that's the most contrasting. Or it'll find the first one to pass a target score. And that's really helpful for design systems because now you can automate whether you're using utility classes or just custom properties. You can automate good contrast in a really healthy, sustainable way that's much more hands-off, which is really nice. But then the final thing in the color functions is relative color syntax, the ability to extract things out of one color to build a new color. And yeah, it turns out color is- Noel: Whoa! Tell me more about that. What does that mean? How does that work? Adam Argyle: Yeah. Okay. Noel: How does relative color syntax work? Adam Argyle: Yeah, you're familiar with de-structuring and JavaScript? Noel: Mm-hmm (affirmative). Adam Argyle: Yeah. I love that. Right? You're like, "Oh, object with all these properties. I'm just going to take a couple of these out of there by name. And now I have them in my hand." It's like these little variables. So if you think about color as being... we've been trained now over the past few years in color to think about three channels. With HSL, it's hue, saturation, and lightness. With RGB, it's red, green, blue. And you're passing these things. So with relative color syntax, you can extract the color channels out of a color into variables, and then you can perform a calculation on them and return a new color. So a really good example is you've got a brand blue, and you want to create a variant. Maybe it's like a hover highlight color. And the brand blue you were given from a designer, very classic. It's just a hex. Maybe the hex even came from a style guide that was made 15 years ago. Right? This is just that company's brand blue. Adam Argyle: So you take the hex color, and you stash it in a custom property or not. It doesn't matter. But you can say color, so you're going to call the color function. Open parenthesis. Well, actually, you don't call color. You specify which type of color you want at that time. So let's say HSL just to keep it simple. You have HSL from hex color, and then you'd get HSL as these de-structured channels that you can then use a calc function on to light and darken, divide, multiply. And yeah, it lets you take blue. Say, "HSL, from that blue, take the lightness and increase it by 10% on hover." So now you have pretty much what you were doing in SAS all this time. You can now do that in line in your CSS on hover and be very dynamic about it. Noel: Nice. Nice. Where do you see that being particularly useful? Because I feel like the argument there would be this seems like a lot of lifting to be doing in CSS functions. Right? Why do we need to pull the hue out of a color and change it, and then send it back in, and it specifically works just like computing that outside of a tool and setting it is a value somewhere. Adam Argyle: Yeah. That's a good question. So if you were doing it in a pre-processor, for example, and you had five different themes in your site, you'd have to have five different... because, Right? It's declarative. You have to have five different entries that define all of these separately. And when you have a function that can do it, it can be very dynamic against a custom property. So something can change a custom property, and all of a sudden, the color gets updated and gets adjusted by 10% on hover just because that's the nature of how you programmed it. So you can get rid of a lot of this declarative code into something very dynamic and reactive, yeah, as an example there. Noel: Yeah, that makes sense. That's a good one. Yeah. So just to make sure I'm understanding, say you've got a hover effect that you're putting on a button when somebody hovers over it that makes it like a little bit darker, for example, so you could always take it and say, "When hovered over, this should just be the darker variant of whatever the base button color is computed as." Is that... yeah. Cool. Cool. Yeah. Adam Argyle: Yeah, it used to have a name called color adjust. So where you had color mix where you mixed colors, there was a color adjust spec function that was very familiar for folks like lighten by 20%, or darken by... And you would have these functions, like these function names in it. But it turned out that the relative color syntax could do the same stuff with less code, and it could do more stuff. So essentially, color just got hacked. It was like, "We don't need you anymore. This new syntax for relative color is way more powerful and more succinct." So that's a good way to think of it, too, as a color adjustment. Noel: Yeah. Yeah, yeah. I think it'd be super helpful, especially if you're building some kind of web app where there's just a ton of dynamic colors or user defined colors happening, maybe. People can set their profile color or something, and then you want to do stuff with that. That'd be awesome to have that toolset there, I think. Cool. I think another one you touched on there that I'm curious about is color contrast. Can you tell me more about what that's for, what that does? Adam Argyle: Yeah. So color contrast says, "Color-contrast, open up a parenthesis, pass in a base color." And this can be a hex or a custom property. So let's say you pass in just a medium blue, and then you say, "Space versus," so vs, and then you list a bunch of colors. And the basic version of the function just checks each of the colors and finds the one with the most contrast. It also accepts an ability to not specify any colors. You just say, "Color contrast against blue," and it will determine if black or white is the better text color for you. Noel: Oh, neat. That's pretty cool. Adam Argyle: Yeah, you can just throw a color at it and then have a good contrasting text color or have a contrasting background color based on text color. It doesn't care about how exactly it gets used, but its basic version finds the most contrasting. But if you want more of a subtlety to your text colors or a subtlety to something else, you can specify how much contrast it should pass. Give it a whole list of colors, and it will find the one that matches that target contrast, or it will pick black or white, depending on whichever of them is closer. But yeah, you get this design system idea where designers usually have a list of text colors, and then you also usually have a list of background colors. You essentially can chuck those at the browser and be like, "Hey, browser, here's the current background color of this little thing. And here's all of my text colors. I want it to be a double-A contrast," and it will find it. And that's it. You get to walk away. Adam Argyle: And the background can change to a new background color. That same list of text colors stay, and they get matched against that other alternative background color. And it'll find the one that passes it. So you get this really extendable self-sufficient contrast system baked right into the browser. So it should make passing your contrast much easier, which is the number one accessibility issue is low contrast text. Noel: Yeah. Is that the default? So if you don't specify anything and it's just choosing black or white based on ... is accessibility parameters what's instructing that default contrast threshold that needs to be met? Adam Argyle: Yeah. It's being powered by the wicked 2.1 contrast spec, which is the one that every tool has been using forever. Yeah, it's the double-A, the triple-A. Noel: Yes. Yeah, that's awesome. Yeah. So then, I'm sitting here like my gears are turning now. So you could have something where you have relative color computation happening, so back to a button. If there's a button with text on it and there's relative color computation happening to figure out the hover color or the click color of that button, and then the color contrast function could be powering the color that is the text in the middle. So then, again, if it's a user-defined color, and when hovered over, the text needs to be white. You could set it up so it's like, "Well, regardless of how the user defines the color, whenever it's hovered over, the correct contrasting color is the one that ends up getting used." If they defined a color that, when hovered, it needs to be dark, it'll turn dark, otherwise, it'll turn light. Is that accurate? Adam Argyle: Yeah, that's a really great example. Yeah. So you've got this theme color on your button on hover. You specify that the text color should contrast against the background, and you'll use a custom property for that. And then, no matter what background color ever gets set on the button, on hover, you'll always be in the best set of contrasts that you can. Noel: Nice. Yeah, yeah. That's awesome. And yeah, to your point as well, having a giant list like, "These are the possible text colors for our app," and just being able to send those everywhere as the text color. Right? Set that and pick the one that we can with contrast and make it work. I guess that leads to an interesting question for me. So when you're supplying colors to this contrast function, and you set the threshold, is the first one that meets that threshold the one that ends up getting used, or is it the most contrasting one? Adam Argyle: Yes. So when you don't specify a target, it finds the most contrasting from the list. If you specify a target, it grabs the first to pass, I believe. Noel: Cool. Yeah, yeah. I think that would make sense because people like you'd say, "Well, the designers say these are our order of precedent. This should be the one we can use when we can." Or else, X, Y, Z. Adam Argyle: Yeah. They usually go to lightness or darkness. Right? You're like, "Here's our darkest text color and our lightest text color." And you're like, "Cool, browser. Figure out the first one that gives me good enough ratio, and I'm out of here" Noel: Yeah. Nice. Nice. Yeah, that's awesome. Yeah. I think you said the other one was color mixing. Where is that useful, I guess, is maybe my question? Why would I want that as a web dev or even a designer? Adam Argyle: Yeah. We did a lot of research against usage of SAS, so we scrubbed GitHub to look at all this open source SAS files that we could. And we found that color mix was the number one way that people were adjusting color, which, to me, it was a little weird because people were like, "Add white. I want to lighten this." So they'd mix it with white, which, I suppose, makes sense. And so why we have color mix in there is because it was just so highly used. We needed something like it. Adam Argyle: And the way it works is, yeah, you pass two colors. You can say how much of each color should be used in the mix. So it's almost like a dominance of this color. I'm going to mix red with white, and I want it to be mostly white, so 90% white mix, and then you get this really, really pale pink color. And yeah, that's color mix. You can also do these color mixing in different color spaces, which is, I think, another one of the superpowers of all of this stuff, specifying that I want to mix in LCH instead of HSL. And that will give you a more perceptual result as opposed to HSL, which is a little bit more variant in the way that you can lighten and darken things. But yeah. Noel: Yeah, that's interesting. Yes. So again, it attracts me that it was a little bit... its surprising to me that mixing is used that much in the web, even just to light and dark. I wouldn't think that's what people would be reaching for. Do you think that is a, I don't know, a healthy way to move forward? I guess if you were making a recommendation to a team writing new CSS, like a clean web app, would you say, "Use the color mix functions, or lean on the relative color functions when you can"? What would your recommendation be? Adam Argyle: Yeah, this is a great question. This reminds me of HSL versus HWB, and they're almost just a bit of preference. I've made color theme systems with both relative color syntax and color mix. I can get pretty much identical results. It's just a legibility thing. Color mix was all... creating my dark variance were all like, "Okay, mix this with black at 25%. Mix this one with black at 10%." And giving me these different darknesses that I could use in my application versus the real ... I think it's just the legibility. So yeah, I made that comparison, HSL to HWB because HSL and HWB both start with hue, and HWB is hue, whitenss, and blackness. And I guess if you're into color mixing and you mix a lot of black or white with your colors, you might like HWBV because that's just the way you think. It colors with a darkness or a lightness in them. So I don't know. I think it could just be preference or maybe how the designer was articulating their colors. Yeah. Noel: Yeah, yeah. Totally. Do you think a mix of both should be shied away from? And in a given project, should you try to stick with one? Or do you think you use whichever one is most appropriate for a given color calculation? Adam Argyle: Yeah, that's funny. I think they each have a little bit of a unique use case. So I prefer the relative color syntax as much as I can. I just like the way it works. I also love de-structuring, and it just feels powerful. But I could see color mix becoming important if you literally want to mix colors. That would be its superpower, whereas the relative color syntax can't mix. You could adjust the hue. You could rotate the hue or something like that and try to nudge it towards another color, but no. You're just like, "No. If I need to mix colors, I'll just use the color mix function." So yeah, maybe that would be my assertion right now. My early assertion is use relative color syntax unless you are actually mixing colors. Noel: Yeah, yeah. That makes sense to me just from our... I haven't like looked at these at all, but just from our conversation, it sounds to me like the relative color sounds more, I don't know, programmatic. It sounds more programming-y, just like de-structuring, changing specific values, and building a new color versus just, "Here's two colors. Give me the middle of them," is a layer of abstraction that is powerful if you're literally trying to mix two colors. But it seems like if you're just trying to lighten or darken, the flexibility of relative color would be... I guess maybe the computed nature of relative color seems like it'd be handy to have there. Adam Argyle: Yeah, I agree. Noel: Cool. Yeah. Any other particular stuff, new stuff, other than color that you're excited about? Yeah, I see layer on the list here. How does the layer selector work? Adam Argyle: Yeah. At layer is... if you heard of ITCSS, I-T-C-S-S, inverted triangle CSS, or in SAS, they've had this for a while also where you could import things into various layers. And it gave you this ability to articulate the stack of styles independent of actual network load time. And you've probably had a huge index dot stylist or a huge index dot SAS file that very meticulously was hand managed. And all of our libraries are imported at the top, and then all of our normalized and resets, and then all of our this, and all of our that... and that was because you were intentionally creating an override scenario. But the bummer was that if anything needed to load outside of that index file, it could load before or after. It'd have to be in the HTML somewhere. Adam Argyle: And you have an asynchronous loading nature, but the way that you were trying to articulate your cascade stack was very synchronous. And cascade layer pops in here and says, "Well, as soon as we see that you defined some layers, you can define them in order. Which one is first, and which one is last? Anything that loads any other time in the page, we can insert it into the appropriate layer that you want." So it's essentially, you get to have your cake and eat it too. You get to articulate it synchronously, but any asynchronous loading gets to go right into those spots. And it just becomes this ... you don't have to worry about it as much. You get to load your libraries really late. So you could lazy load your libraries but still pop them way up high into the cascade. So it's neat. Noel: Yeah, yeah, yeah. Interesting. I'd probably have to sit on that one a bit more to fully realize the power of it, I think. It sounds like it'd be hard to manage. Is there a layer of planning and, I guess, understanding of the nature of asynchronous loading that one would need to have to use layer well? Is that true? Adam Argyle: I think that is generally true. And you're right in that at layer has some complexity it's bringing with it. So I mentioned that one use case as a loading strategy, but at layer has a second superpower, which is that these layers also create their own scopes. And the scopes do have specificity. So, for example, styles not in a layer have more specificity than styles in a layer. And so knowing that, or not knowing that either gives you a superpower or becomes something where you're like, "Why is my style not working? I put it in a layer, and I don't see it. It's being overwritten by this other style." And if you don't get how your layers are working, you can get yourself into some issues. But yes, it does have some rough sides, but it can really help you also seclude different things and create these more controlled stacks of styles and overrides. So yeah, it depends on how intimate you are with the cascade, how much you are playing into inheritance and extendibility, and that sort of thing. Noel: Yeah. Nice, nice. Yeah. Any others you want to spend time on? We don't have a ton more time, so I want to make sure that we talk about the stuff you're excited about. Adam Argyle: Yeah. I mean, at container and has, has been... traditionally, a selector only lets you go to the item at the end. So you'd be like, "div space p," and you'd only be targeting the paragraphs. And has lets you flip that. So people think of it like a parent selector, which it can be. So you could select the div that has a paragraph, and that's easy use case number one. But you could use has in the middle or at the end, and it can really ... Okay, so if you have a radio set, you could now change your whole application based on what choices they're making in that radio set anywhere in the tree. And you just get this brand new reactive superpower to the state of the tree changing styles other places. And that was really cool. Adam Argyle: And then you have at container, this ability to look to see how wide or tall my current container is and adjust my flex, adjust my grid container or grid columns. And then, even coming soon is the ability to at container query the style of something. So you could say, "Is this container display none? Does this container have overflow auto?" And then you could adjust your styles based on these things. So querying the size, querying the style, and then even after that is querying the state, being like, "Is my container stuck, or does it have a snapped child?" And these more advanced stateful things, you being able to query the container for those and adjusting yourself accordingly. It's cool stuff. Noel: That's super cool. I guess, yeah, one quick question on the has class. Is it a pseudo-class, technically? Adam Argyle: It's a pseudo selector. Yeah. Noel: A pseudo selector? Adam Argyle: They're a pseudo-class also. Yeah. Noel: Either way. I guess that kind of observation and reactivity that it gives devs, I feel like those kinds of paradigms can be a foot gun sometimes. And you end up getting yourself into trouble when you can set these things, and just, you end up with this system that's very complex and brittle and changing. When you're refactoring or trying to make changes, you end up like, "Oh," inadvertently breaking all this stuff because you got these hard-to-trace lines of reactivity, I guess, like functionality that changes somewhere based on somewhere else. When you're looking at something like this has class, do you think about that at all, or is that a concern that comes up in discussions? Adam Argyle: Yeah, definitely. That was one of the reasons has took so long. It was a known performance issue. I mean, yeah, you could have has inside of has or another has with another has. And the way that they were doing performance optimizations before is they were looking at the furthest item and moving backwards up to selector, and then they had to come up with new performance patterns to account for the potential impacts of has. So yeah, has can get you into really complex scenarios. It can maybe get you out of a complex scenario also. Yeah, all of these things are really interesting to move into the view layer because they felt like they should be there. Adam Argyle: And we were doing all of these really nasty hacks before this where we were looking at adjacent siblings with the plus selector, looking to see if a check box was checked or not. We hid the check box and all of this really weird stuff, but now we should be able to really articulate a little bit clearer here. There is a future of state machines being in the browser, too, with the toggle function. And so, if you're wondering how to map all that complexity and all that state, that syntax could really help if you think state machines are an easier way to model UI. Noel: Yeah. I mean, I think UI is a particularly applicable case of using state machines to keep track of the possibility. So I think that helps a lot with this kind of concern that I was trying to bring up. I don't know how to edit. It makes me scared to edit this stuff anymore because I don't know what all selectors are going to be based on it, and I'm going to inadvertently break things that I'm not even looking at when I'm editing this given file. Right? That's the fear that I'm trying to curb, but I feel like if you've got a statement- Adam Argyle: At scope is good there. Yeah, so at scope lets you. You're like, "Oh, well, I'll just stick all my has working in here, and then I know it's all scope." It's almost like- Noel: It's contained. Adam Argyle: ...CSS modules, but plus. Yeah, you can contain it because yeah, I agree, CSS has this nature of where it's like, "I'm global all the time." And people are like, "Well, that is freaky because I work in this very scoped mental model all the time." And yeah, I guess scope is helping you bridge that and making sure that your styles are very secluded to something specific. Noel: Nice. Yeah, yeah. I mean, it sounds like there's stuff there for everybody. Depending on the concerns that you have, there's tooling being added to make it easier to factor those in. So that's super awesome to hear. Yeah. I guess, is there anything upcoming in the near or midterm future that isn't necessarily ready to be explored or usable yet, but you're excited to see it coming out? Adam Argyle: Yeah. I mean, I have some selfish ones in there. So I was talking about scroll snap and how there's some new specs I'm working on. And those are things for... I mean, some of them seem really obvious. Scroll end is not a function on the web, so you have to write your own, and that seemed silly. I like to have snap events so you could snap to something or have an easy way to do that. But the two main ones that I'm most stoked about are the snap target pseudo-class. So if something is snapped, it would match this snap target pseudo-class, and you could go change its state. You could give it a shadow and lift it up since it'd be snapped. Adam Argyle: Another one is scroll start. So if you have a scroller that needs to not start at the beginning, instead of using JavaScript that has to wait for the page to load and do all the shenanigans, put it in CSS. Say, "Start at this element," or, "Start this far from the scroll position." And so it's these little additions to really help you gain control of scroll and create beautiful scroll experiences. I'm excited to see where that's going. Noel: Yeah. Awesome. Awesome. Cool. I guess, yeah, more broadly, anything else you want to plug? Anything you want to send listeners to check out? Adam Argyle: No. I mean, the dev tools, we try to come out with dev tools that come out with all these features so that they are a little less complex. At layer has dev tools that came out with it. We have scroll snap dev tools. Sub Grid will have dev tools. But if you find that the dev tools leave you wanting or that there's something that you can't see, hit me up on Twitter. We love talking about how to make dev tools complement our developer experience better. And let me know what you're thinking. I'd love to hear it. Noel: Nice. Nice. Any other projects or content you want to plug? Anything else? Adam Argyle: Yeah, GUI challenges. I have a library called Open Props. They're just free custom properties to go use. They're super powerful. And you just get to go, "Hey, give me a gradient," or, "Give me a shadow." And it's just this superpowered shadow that you don't even have to worry about. Yeah, those are two plugs. Noel: Cool. Yeah, we'll take it. We'll take it. Yeah, we'll try to get links in the show notes to all that stuff so listeners can find it a little bit more easily. But yeah, thanks again for coming in and chatting with us, Adam. It was a pleasure just as last time. Adam Argyle: Of course. Noel: Yeah. Adam Argyle: Awesome. Yeah. It's nice being here. Noel: Of course. Yeah. Take it easy. Speaker 4: Thanks for listening to PodRocket. You can find us @podrocketpod on Twitter, and don't forget to subscribe, rate, and review on Apple Podcasts. Thanks.