 Curious about the state of CSS in 2022? I'm Adam Argyle, and I'm super stoked to break that down with y'all. Spoiler though, it's hot, it's rapidly changing in all the right ways, and designers tune in because there are rad goodies in here for y'all as well. But first, a surprise, because we know it's hard when you get new toys but you can't use them because of cross-browser compatibility. Well, last year, five style features were focused on and made incredibly more stable – sticky positioning, aspect ratio, flex box, grid, and transforms. A team listened and they heard compatibility was a pain point when developing for the web, so they hacked on it. Well, that team in 2022 went next level. This year, the major browser engines agreed together on what to focus on. I know, it's huge, and not only is the list here amazing, their collective goal is to complete them by the end of the year. Just look at this list – at layer, color spaces and functions, containment, the dialog element, form compatibility, scrolling, subgrid, typography, viewport units, and even more web compatibility. Stable features, browsers hacking on them together, life is good for the web.dev. That's the surprise. So let's get nerdy and dig into what's fresh in 2022. Recently stable and first up, see the browser icons with green underlines there? Is cascade layers, also known as at layer, allows you to customize, control, and orchestrate the cascade. A CSS language feature for wrangling asynchronous loading and third-party styles. Styles can load late in a page life cycle, but be placed into an upper layer as if they were loaded first or second to begin with. So no more meticulously hand-managed CSS loading, just let it load, let it load whenever it wants, assign it to one of your predefined layer nodes. For example, here on the left, before at layer, style imports are grouped and meticulously managed so they override in the order desired. But with at layer, you can define the groups in order up front, then let whatever loads layer append into a controlled cascade layer. And there's even more features of cascade layers. Check it out on web.dev or mdn for more information. And also don't miss the dev tools where you can see an overview of all the layers, see when styles are in a layer, and layers are organized just like you'd expect. Boom, subgrid. This one is a huge win for web layout. Firefox has had this feature for a while, but thanks to Microsoft and the interop efforts, 2022 intends to catch up in Chromium and WebKit. So designers often have page-level grid lines that they align tons of children to. Well, that's a capability of subgrid. There's a grid on the body of this page with line names like full bleed and main. The paragraphs and headlines are aligned to the main and the article image is full bleed. It's so nice. And here's the CSS for that grid and those defined lines. Gutters are set to auto and the main is set to 60 characters or 90% on smaller screens. The children of that grid are given display grid to with their columns set as their parents with well subgrid. Main content assigns itself to the main column grid later like this and full bleed content can span the whole page like this. Wipe your hands clean and that is it. And also the dev tools for rock. You can see which grids define lines and which are adopting them. See the lines on the page with their names and their sizes. Another 2022 interop effort feature is container queries. Before container queries, we could adjust elements to the page viewport without media. And after container queries, we can adjust elements to the size and styles of a container components responding to containers instead of containers adjusting children components owning more of their own styles. Check out this rad demo by Unicravates from the Chrome team. Event components, you know, like you made a new event on a day are shown adapting to their container day columns space. So even though the viewport is being adjusted, the components are only watching their column size. Styles change based on how much column width is available. The demo could change to a one day view or a three day view and the event components would adapt. Speaking of which, there's a demo that does just that. Watch the book component here. It adapts itself to each section differently. Layouts and styles based on container. One component, many built-in adaptations. Demo credits here. Go to max box, rad demo max. Okay, let's see some code. First, you need a container that can be queried. Specify what kind of queries it supports and give it a name if you want. Container type accepts inline size, like width, block size, just size or style. Yeah, style. Be able to query a container style. Interesting. But for now, let's focus on size and that calendar day container. Later, use the container syntax to query that day container and see if it's 200 pixels or smaller. If it's true, those elements selected inside will apply those new styles, just like media queries. You could change from square images to rounded images, card components that go vertical or horizontal, all intelligently. Lots of amazing design and UX possibilities here and there's even a polyfill so you could try it today. Don't miss Jess Lynn Yen's Google I.O. talk on DevTools. It'll show you how to debug container queries. Next up is accent color, available everywhere already. Safely and easily tint built-in elements. Bring your brand color to your forms with one line of CSS and the browser will ensure that there's proper contrast between your color and the checkboxes and the tracks. You can tint everything like you see here in root or tint contextually with a targeted selector. Pro tip, use a media query to check for lighter dark theme settings and adapt your accent color to fit better, kind of like this. Here I switch from hot pink to light pink for users with their system in dark mode. Now my built-in elements are adaptive and tinted. Color is exploding with features in 2022. We have new color spaces, more colors, built-in color manipulation and auto contrast functions, all of which are feature goals and interrupt 2022. First up is HWB, standing for hue, whiteness and blackness. And it's an intentionally humanistic way of thinking about color. Here's a quick demo overview. We have five swatches all with the same hue of 200. Then I adjust the amount of white or black in each. Swatch one has 75% white with no black, giving us a light blue. Swatch number five has no white and 90% black, a dark blue. HWB is pretty cool, but there's way more. CSS color is about to be unchanged from SRGB, the only color space that's been available for like 25 years. 10 more color spaces are coming. You can reach into these color spaces for colors or mix and interpolate with inside of them. Safari Tech Preview has these already available to try. So currently, CSS can only show colors from that inner triangle, SRGB. Display P3, one of the new color spaces can show the outer triangle. Other spaces can reach even further into that color diagram than Display P3. Color gametes are the amount of colors to choose from in a space, and I like to think of gametes like fruit sizes. Think of SRGB like a kiwi and Display P3 like a mango. The bigger the fruit, the more colors you have to choose from. And Leah Varou says, these are not just any colors, but the most vivid colors the screen can display. And she's right. And maybe more colors doesn't sound that interesting, but you thought you were picking hot pink in your color picker. But if you change the color space you're picking from, look at all those brighter colors like an LAB here, get a hotter pink. And it doesn't stop at just more vibrant colors either. With new color spaces, there's also new shapes to work within. The RGB cube, maybe you've seen it, is suspiciously neat-shaped. HSL and some others, they're cylinders. But look at CIE lab on the right there. A new color space for us in 2022, it's kind of funky, right? It's all stretched and contorted for different colors. It's because SRGB spaces are math-driven, where the shown CIE space is human perception-driven, hence the imperfect shape. CIE color spaces also feature optimizations for human perception of lightness, called perceptually linear. This makes it awesome for mixing colors, like lighten this color brand by 20%, and it will match your human expectations. Gradients are massively influenced by color spaces. Here's four gradients, all deep pink to cyan, shown in four different color spaces. SRGB in the top left travels in a straight line between the two colors, through its cube, going through the middle of the cube, and making kind of muddy colors. Lab and LCH though, on the bottom, they don't travel through this color dead zone. So you thought you were getting beautiful web gradients, but SRGB can only do so much here. Here's some of the new color syntax for accessing these new colors. I call the first LCH color there UX gray, because it's 50% from a perceptually linear space. AKA, it's 50% gray is not math middle gray, it's human centric middle gray. Then I create a couple hot pinks, picking vibrant colors with the lab and LCH functions. Then there's the color function, accepting a color space and three numbers for each of its channels. I use it here to grab hot pinks in display P3, lab, and SRGB. You can progressively enhance your colors too. Of course, it's CSS, the dynamic range media query lets you know if the device is capable of HD colors, and the at supports query checks to see if the browser understands the color syntax before you use it. There's so much more here to study. Watch out for web.dev blog posts about it. Coming to a browser near you in 2022, Color Mix. Use CSS to mix colors on the fly in the color space of your choice. To use it, call Color Mix and give it two colors and get an equal mix of each in LCH, the default color space, or pass a percentage along with the color, which specifies how dominant the color is in the mix. The second example there uses a brand hex base and mixes it with black to create some darker all colors. And I know I've been stoked on like everything so far, but this one is magic, pure and incomparable magic. Let the browser pick accessible colors for you. Automate good contrast. So here's four surfaces, all shown with the same paragraph content inside. Each is using color contrast function with a range of brand hues to target the ratio AAA. Notice how the lightest and darkest backgrounds get the more subtle text colors and the brighter surfaces get black or white text colors. I got to bake in good contrast into my CSS and give it up to the browser. We let the browser manage this. This is how it works. In this first selector, I created dash dash bg variable and assign it to the background. For the text color, I call the color contrast function and pass it the bg prop and without any options passed, color contrast will choose black or white for me. But later in some other selector, change bg and the text color automatically picks up white or black based on the new background color. It gets better. So it's cool having black or white picked for you, but those are usually last resort text colors for designers. So check this out. I call color contrast again with a background variable in this case a brand blue. And then I pass three different text colors from a design system plus a AA target contrast ratio. I used AA here, but you can also pass a custom number. Now the browser will pick the color that's closest to passing the score. So you can just throw a bunch of text colors at this function and it'll ensure you pass. And if none pass, black or white will be chosen for you as a fallback. Rad, right? And there's even more color stuff coming too. Check out relative color syntax, another color game changer. It allows you to extract new colors from existing colors. Let me show you. In my career, so much of the color code in my CSS has pivoted on a brand color or maybe two. And in this code sample, I put a simulated brand color into a dash dash color problem in the variable called ABS change short for absolute change. I create a new LCH color from the variable and set its lightness to 75% keeping the chroma and the hue. I call it an absolute change because I threw away the lightness from the hex and gave it a new one. The var REL dash change is a relative change example. I again started new LCH color and I keep the lightness but I decreased the chroma by 20%, keeping the blue hue and the lightness. It's a relative change because I adjusted it relative to the source color value. I think of this relative color syntax like destructuring in JavaScript, you destructure the color channels out of the color directly into a new color with an opportunity to manipulate each channel along the way. It's so rad. It gives me the power to create perceptually linear palettes with very, very little code. And here's what those palettes look like that I made with the relative color syntax in the LCH color space. I wrote the relative color logic one time and it takes a base color and generates a palette. Then I use it for all 15 palettes here. Give me a brand color and I'll give you a perceptually linear palette back. And notice how smooth they are too. No hot spots thanks to LCH. That perceptually linear color space is super handy. So be stoked to see CSS producing these incredible colors and smooth palettes in the web in 2022 y'all. But 10 new spaces mean 10 new gradient variants to choose from. Let's take a look. On the left are gradients simply going from black to white. And on the right are gradients going from blue to black. Today you get the top gradient, the sRGB interpolation result, which is generally fine and consistent. In 2022 you'll get to pick from any of the others below it. And you see what I mean. There's 10 new gradient variants. The color space is super important. The variance in just black to white is intriguing. But the blue to black gradient is going purple or pink in the middle? What's going on there? Let's see a couple more examples. On the left is red to white and some turn a bit orange. One goes pink and some go through that dead zone in the middle. On the right is blue to white. Most go purple in the middle, but OKLab and LCH stay nicely within hue. Interesting, right? So I expect designers to start specifying which color space they want their gradients in after they get these tools. And here's the syntax to linear gradient that allows you to do this. That allows you to access the color space. Linear gradient, you call the function, say direction to right and the space in HSL or LCH and then your set of colors. It's pretty straightforward change with really big results. Last in our color set here is color v1 fonts. They're a new smaller color font format with embedded vectors that allow gradient and blend mode customizations. It's an evolution of the OT SVG fonts, but they're smaller and with more options. It's great for icon fonts, awesome headlines, and tons more. So before color v1 fonts, we had these OT SVG fonts, colorful, editable, and really playful, but the styles are fixed. After color v1 fonts, like Placato here, customize the font with at font palette values. These let you to find parameters to pass into the font, very similar to variable font parameter passing. You can tailor the color font to meet your needs, and this could be a huge win for icon fonts and more. To use them, import color fonts like any other font with an at font face declaration, or grab them from Google Fonts with an at import, which will include those goodies. Next, create an at font palette values block with the name colorized as used here. Then specify which font you're targeting and pass some overrides. Later, assign the font family with the color font and specify the custom font palette, and that's it. Next up is inert. This allows developers to specify which part of the document should be inactive. Think of it like freezing portions of the document. You can use it for keeping focus into a certain part of the page by making other parts of the page inactive. So originally started by Alice Boxall, now a Gallia is carrying it across the finish line in 2022. The alert JavaScript function is a good example. Once that pops up, the rest of the page isn't interactive. Keyboard and mouse users are being guided into the area where their action is required. To achieve this, let's look at some HTML. Here a modal is shown, and the main element is given the inert attribute. Now mouse and keyboard users have proper focus into the modal because the main element is frozen. Node.js or tab index attribute traps required. This is a really cool accessibility win and expect to post from it on web.dev. Another goal of Interop 2022 is enjoy a bunch of new viewport unit variants that you can really hone in that full viewport feel. New units allow you to specify smaller viewport size as if the mobile tab bar is showing. The larger viewport size as if the mobile tab bar is hidden or dynamically be both depending on the presence of that mobile tab bar. You have 20 new units to fit this viewport with physical or logical values. Here's all the new physical and logical viewport units. We have 100 VH, 100 dynamic viewport height, 100 small viewport height, 100 large viewport height, and then there's the logical direction block versions for internationally adapting full screen layouts, then the complimentary width versions and the logical inline versions. But you can't forget the min and max viewport units too, each with small, large and dynamic versions representing either the smaller of the viewport height or width or the larger. Hopefully these unblock lots of folks making full screen app experiences. Ah, colon has selector. This is easiest described as the parent selector, but that sells it short. Think of it more like I'm no longer forced to have my target element at the end of a selector. I can change the subject of the selector if I want. This one is being implemented by Gaia, recently stable in Safari and an Interop goal in 2022. Here's a few examples. The first selects the parent class if it has a child in its tree. This can be amazing for a CMS or layout to know what kind of blocks it needs to make space for. The second example selects a section element if any of its children have focus visible. I like this example because it shows how this selector will affect interactivity and UI feedback. But let's look at a couple more examples. The first selects anchor elements, wrapping images. And the second finds images that are inside figures with fig captions. So see how it's not just a parent selector. This last example selects images if its parent has caption elements, right? It's amazing. So expect has to be a huge game changer combining it with pseudo selectors and nth match notation selectors. It's going to unlock some very powerful state and style. Quite a lucky time to be a web developer. Be sure to check out my blog post on this talk where I go into even more detail about these topics and more items. Find me on Twitter, web.dev, and YouTube sharing gems and tips about front-end UI and CSS. I'll see you later, y'all. Hope you're stoked now too.