 Hello, welcome to Designing in the Browser, the series where we explore user interface design through the lens of modern web technologies. In this season, we're going to do a deep dive into the APIs that prepare you for the new responsive web of tomorrow. If you didn't catch the last episode on container queries, definitely check that out because today we're going to be elaborating on some concepts introduced in that episode and expanding beyond how to use container queries into the question of when to use container queries versus another layout algorithm and how to combine them. Layout is a critical component of user interfaces, and as the complexity of our interfaces grows, so do the options we have for designing layouts for them. Design systems enable developers to think in terms of component-based architecture and separate page designs from component-based intrinsic designs. Until recently, this has and largely is still pretty limited. The way we're forced to sell pages is still focused on a global first approach, but with container queries, developers and designers can finally truly divorce macro, more global page-level layouts from micro-intrinsic layouts that are owned by the components themselves. Let's start big and then go small. This is how I like to paint, write styles, and create UI designs, from broad strokes to more detailed polish. Macro layout generally refers to page layout or application layout from a higher-level point of view. This would be how you break down your web page, where the header goes, the body, the sidebar, etc. When it comes to designing for responsive screen sizes, macro layouts shift and reorganize to best fit available space. It wouldn't be a very comfortable mobile web experience if you were just browsing a zoomed out desktop version, and vice versa on wider screens and narrow layout is difficult to parse, especially if it's expanded to fill the wider area. So items might stay or hide off-screen to ensure that the primary content is always at the forefront and available to the user in a format that best fits the screen. When there's more available space, more sections might become visible to fill the space and areas might grow or shrink to fill that space. Macro layouts tend to work well with CSS Grid because the CSS Grid layout is a two-dimensional layout algorithm which enables developers to define both horizontal and vertical spaces. It also lets you place content within those spaces. This makes it ideal for creating layouts like the Holy Grail layout and other full-page bird's-eye view spreads. This Holy Grail layout can be written in CSS Grid using just a few lines of code. What we're specifying here is I want to create a page layout on the page layout element. I want to make the row template auto, which means it takes up sides of its children, 1FR and auto. This places the header and footer at the top and bottom of the page, and the content within it takes up one fractional unit of the remaining space. So if we're setting the height of the entire page to 100 VH, that would let the remaining space of the page, the 100 VH viewport height, be that middle section. Then I want to make the columns take up 200 pixels, that's the left and right sidebar, and then the middle space, the center of it, would be 1FR unit, which is the remaining inline size. From there, we can also place items in this grid, like so. And altogether, it looks like this. If we let that center section stretch to fill the space, and all of this quickly is adjustable in just a single line of code using the grid template shorthand for both the rows and columns. And here's what that looks like altogether. So we have our full layout. Here I've set this grid on the body, and the grid template is written here as auto, 1FR, auto. I have my 100 VH. If I don't have that, you can see that it collapses. So that's important to make this all fit into this viewport. And I could, of course, adjust these so I could set this to 100. I could make that also a relative unit value instead of an absolute unit value. There's a lot that you can do a CSS grid layout in just a few lines of code. I think that's super cool. And then you can see that I'm placing something like the header to span across three of those grid lines, starting at the first one. So I could place this habit, span just two of those lines. But currently, I'm just using intrinsic placement for the left sidebar, the main section of the right sidebar so it would have everything flow up a little bit. I'll show you what that looks like. It kind of breaks our layout. But I could also be placing everything else explicitly. I just wanted to do this so that it shows you that you could place some things explicitly and then some things will flow into the remaining available space. At some point, though, this layout might feel pretty squeezed. See, as I'm doing this, the main section is getting really squeezed. So we might want to create a media query to adjust the grid or to span items across the grid in a different way. For example, we could hide the right or left sidebar in a pop-out menu. And we can expand that main content section. Or we could just stack that content vertically at some point. So if it was on a mobile or more narrow design, we might want to stack it. Media queries are great for these types of page-level adjustments. So what that might look like is this. We have the same layout. But with this one, we have a media query. So it's getting squeezed. Clearly, this is like a demo, because the main is way too squeezed there. But then at 500 pixels, we have this media query that's doing these adjustments where, on body, we're setting a new grid template. So here we're setting auto instead of 1FR for that single space. We're setting three rows with repeat 3.1FR. This is a grid function that we can use as a shorthand. And then auto for the footer. So what this looks like expanded is auto, 1FR, 1FR, 1FR, auto. And then we're setting the grid template columns to 1FR. So if we're writing it in one line of code, it looks like this. There's a really handy little button and dev tools that I could trickle down to see what that looks like expanded. So it is a shorthand for grid template rows and grid template columns with that slash in the middle. And it rearranges to fit into our UI a lot better. So we can use media queries for these macro layouts when we want to place items on the grid or just have it look a little bit neater. There are also a lot of really neat functions in addition to repeat that come along with the CSS flexbox and grid specs that make automatic responsive layout without media queries possible. One of those is the CSS grid minmax function. This is one neat way to create an intrinsic layout grid without the need to use media queries. These children have a base minimum value of 150 pixels with a maximum value of 1FR, fractional unit, meaning on smaller screens, they'll reach the full 1FR width. And as they reach 150 pixels wide, each they will start to flow back up onto the same line. And here is what that looks like. We have a new section on the web.dev site called layout patterns that pulls all of these different patterns together. And this one is just exactly what I described with the repeat auto minmax where you have these fitting onto the same line. And so you see that this is going to fill that area as best it could, but it creates this automatic repositioning of this grid as it tries to fit into that area. So there is some automatic intrinsic design that can be done within something like the grid layout. This layout can be considered both a macro layout and a micro layout, since it can live inside of a parent layout, but it can also contain its own children with their own layouts. I also frequently use the minmax and clamp functions to give elements flexibility in their sizing while maintaining boundaries like a minimum and maximum size. I also have a demo of this clamping card here where it's doing exactly that. So we have this width that has a minimum size of 23 characters, a maximum size of 46 characters so that the text within it is still legible, and an actual size of 60%. So we're always going to try to be 60% of this width here. And as every size you could see, it's increasing in size up to a point and it stops increasing in size, it's hit its max, and then when I decrease it in size, it decreases to a point. When it hits its minimum, it stops doing that. So we use this all over the Design Sember website to give things parameters while they can still be flexible in between. This gives me that intermediary control, setting parameters of what is the allowable display area and giving it room to be fluid in between. Now let's get into these smaller components that make up our web pages. Micro layouts are smaller component level layouts that live within macro layouts. Micro layouts work particularly well in component-based architectures where elements already contain and own their application logic. With container queries, you can now co-locate those component-based styles with that logic within the individual component. Like macro layouts, micro layouts can adjust based on their available space. You can do this either with some of those responsive intrinsic capabilities of Flexbox and Grid or with container queries. Responsive graphics or media can be an example of a micro layout that lives inside of a given media space on the page. Cards that contain sets of information could also have their own micro layouts within a larger grid and act independently of that grid layout. Typographic layouts can also be nice micro layout moments throughout a UI. And even something as encapsulated and small as a call to action button can have its own micro layouts with container queries. So let's take a look at what that looks like. If you saw the last episode, you probably recall this add to cart button. And I just want to show you how cool it can be to give this its own intrinsic design and its own micro layout. So this add to cart button has a container and I am giving that cart button container, this container in line size so that cart button can then query that container. So here as I resize this, you could see that it's readjusting its styles. It has this plus sign with the cart and add to cart. Then the plus sign goes away. Then the to cart goes away, just says add. And then this is going to continue to shrink. The detail on this cart is gonna go away because it's getting too small. And then finally I have just the cart. So this is a great way to showcase how any small part of your UI can have its own micro layout. And I can put this card within another container. So again, just to show you, here is a product card. This one is a planter. I have this add to cart button within that planter container. And then as I resize this, that add to cart button knows that has its own responsive style, its own micro layouts that lives within this intermediary layout, which is acting like a micro layout in this case of this card. And then there we go at this wider width, even though the card switched layout to its smaller layout width, the button itself is at its wide width. So it's super cool to see how all of the stacks, it's super modular. And to see how we can make really customized UIs using a mix of all these responsive mechanisms that the web gives us. So let's break down how I did that. First, I planned out the different views I wanted at each breakpoint size for the card content. So it goes from just the cart without line detail, then I add the line detail, then the little plus sign, and then I have the text say add, and then the full add to cart. When I layered it, this is what it looks like, except instead of the SVG text, I'm using DOM text for the actual button as I showed in the demo. Each of those numbers corresponds to a query step with one being the smallest size, and five being the full size. I also add space between the cart icon and the text as the text appears. So again, within the UI, it looks like this. It's expanding, it's filling the space, it's appearing at all of these different steps and stages, and it's doing all of this through container queries. It's super, super cool to see that, to see it shift, to see the cart icon rearrange, to make the plus appear, disappear. The possibilities really are endless. So here is an example of typographic micro layouts. So in this example, I have this calendar component, which is the grid, and then inside of this calendar, I have these days, which are columns, and then within that, we have the date. So where we're setting the day, which is the day number and the day of the week, so Thursday the 12th, Friday the 13th. These are actually shifting based on their given available space from this inline layout next to each other to this block layout where one is on top of the other and the size of them changes. So what we're doing here is within the calendar, we have this day, and then that itself is a container. So that container is being queried by both date and within events, these items are also querying it. So let's just look at date, because this is one example of a typographic micro layouts. So here it's going to be shifting, it's getting that display block at this max width, and then here you're gonna go back to display flex so that it's gonna be one to one next to each other, also adjusting the size a little bit of height variation, but that is just one example that when we go even smaller, it's gonna go back to that wide view. So another thing to look at is these individual events within this demo. So here, the font sizes of them are actually gonna start shifting. So here you can see that they are a little bit bigger, and then at a specific point, they will adjust to be just a tiny bit smaller. And that is just one example of another small adjustment that can be made, here they've grown, here they're just a little bit smaller. Another example of a typographic micro layout adjustment, so that things are just fitting a little bit better into this UI, just like they do with the dates, with the day of the week and the date number. When you combine responsive macro and micro layouts, you can control the larger view as well as the smaller views, and you get a really flexible and fluid design that looks great at any screen size and parameter. Combining media queries for macro layouts, intrinsically responsive grid and flex box capabilities for the intermediary layouts, and container queries for micro layouts brings you a ton of control, yet flexibility to your interfaces. And for more of these patterns, we recently launched web.dev patterns, which is a collection of off the shelf UI patterns you can use in your web projects. To help you quickly get started with building the base of your UI, we've added both macro and micro layout patterns, everything from large full page spreads and card sets, to smaller layouts that can live within those larger layouts, such as the cards themselves. Definitely check those patterns out for more, I also included a container query card pattern as a demo, as well as some of the other macro and mid-tier layouts I mentioned today. Most of these layouts were cross browser because they utilize CSS grid and flex box. It's a lot of fun to play with these patterns and especially layer them. I love the modular aspect of containers and it's just so rewarding to see it all come together. I hope you get a chance to check the pattern templates out and as always, I'll see you on the internet. Until next time. Okay.