 Welcome to Designing in the Browser. In this series, we explore how to take a design, build it, and then tweak it in the browser using the latest in web technology and design systems. Today, we're going to take a look at how to build a layout that scales across mobile and desktop views. That's right, we're talking responsive design and how to make existing components work in the context you intend. There's so much talk about, so let's dive in. Size-based media queries are the first tool we have for responsive design. You write media queries in CSS with the at media rule. We usually want to design mobile first, so we think of our smaller screen styles as being the baseline. And then we use media queries based on our browser's minimum width to adjust for larger screen sizes. Here's a demo with that image list that we saw in previous episodes. And what I want to show you here is this device panel. So you can toggle it on and off by clicking on this little icon here with the two devices. And inside of that, we have a variety of options. We have a responsive sort of option view where we can open and close this horizontally to see what it looks like at various screen sizes. We also have shortcuts with various devices. You can swap the view from horizontal to vertical and vice versa. You can really see a lot of various options for default styles. And again, you can make customized layouts and sizes using this responsive view or even adding it as one of your own defaults. We'll go through some of these dev tools more in the next episode, but this is definitely one of the ones that I use the most. Let's do a quick look at the code on this as well. So here we have from the most baseline position, the default, which is one column and no padding between. Then as we get a little bit bigger, 500 pixels, that goes to two columns with eight pixels in between. At 800 pixels, it goes to three columns, 16 pixels in between as the margin between those images and so on, it gets bigger. So here we have an example of responsive design across browsers starting from a baseline of mobile and getting bigger as the device changes in size. Media queries are not just for the size of the device that you're in. They can also detect the device aspect ratio, pixel density, print mode, orientation, and a lot more. There are also many new accessibility features which detect user settings that can now be accessed as media queries. These include prefers contrast, prefers reduced motion, prefers color scheme, and prefers reduced transparency. These features are new to the web with the latest version of media queries, but they point to this much more responsible responsive design that we see in the future. Those are all super cool and important to know about when designing responsibly, but for now, let's get back to layout. You might not always need media queries when styling layouts. There are a few CSS properties that will automatically calculate changes and apply them based on the width or height of the browser, eliminating the need for media queries. For example, the Flexbox and Grid layout properties have calculable properties and auto placement modes. Flexbox is a layout algorithm designed to allow elements to stretch or shrink and best feel the specified available space based on their intrinsic size and the context within which they live. Flex layouts can be both horizontal and vertical. They'll stay in a single line by default, but can also wrap to fill the space. Alignment is an important concept that's in Flexbox too. I'll show you what that looks like right now. First, I'm gonna give this a little bit of height. So maybe 600 pixels, so there's a little bit more space. And you can see that these are automatically stretching to fill that space. So in order to adjust that, I can use the align items property. And maybe I wanna start from center. Here I'm aligning the items at the center. You can also align them at the flex end, the flex start, or anywhere in between. There's a shortcut inside of Google Chrome where when you start typing a property value, it auto completes your options. So you can actually just go through this list and see where your options are in terms of alignment. Justification is another important concept. So you can justify the content in the same way that you align the content. With justification, like alignment, you can adjust where these items live inside of its parent container. But with justification, because this is horizontal by default, this is going to align the items within that horizontal space. So say I wanna justify them as space between. This aligns the elements with the space in between each other. There's also a few different properties that we can play with here. There's space evenly to space them all evenly centered inside of that horizontal row. There's center, which will just shrink them all together since there's no margin around these items. And just like the other property of alignment, there is an auto-completed list, which you can sort of just go through and see what your intended visualization is and your intended effect is. With Flexbox properties, we can start building more flexible and responsive designs. Items will shrink and stretch and change position without the need for media queries. Here's an example where all of that is tied together. A responsive layout with no media queries, all using Flexbox. Here's what it looks like. I have the header section. I have a left sidebar. I have a section of these cards and another sidebar as well as a footer. And if I open up this device panel, you can see that with this responsive device, I have all of these views visible. As I resize this, the items are shrinking to fit the space. And when it hits a point when their flex sizes don't fit, it will then be pulled over to the next row. This is using the Flexwrap property where it's going to wrap onto the next row. As I continue to resize, this layout will actually adjust itself by adjusting the sidebars to be next to each other underneath the card block. So we have multiple points in which Flexbox is creating adjustments independently of elements throughout this page, which is really cool. It's kind of like creating a micro layout within your page without even needing media queries. However, the real wins happen when you combine these technologies. You can combine media queries with Flexbox and you can also combine these with another technology called CSS Grid. CSS Grid is the newest layout algorithm with support across all evergreen browsers. It's super powerful and unlike Flexbox provides a structure both vertically and horizontally at the same time for an entire page or elements. The way a basic grid works is you explicitly specify a grid template and define how many columns, grid template columns and rows, grid template rows are in a grid and then place its children into the grid using grid column and grid row. You can also use the auto keyword when defining this template to automatically fill children into a grid. We'll go over that a bit more as we highlight just how powerful and responsive CSS Grids can be. Here's an example of placing elements into a grid. So in the HTML we see, we just have a bunch of these little boxes inside of this body here. And so that's what we're seeing up here on the right in our code. And if I resize this, you can see that these are actually adjusting based on the CSS that I've written. So the first two columns are not moving and that middle column is getting wider and narrower and then at a slower rate, that column all the way to the right with the four and the eight is also decreasing in size as the screen size gets smaller and increasing as it gets bigger. Now let's look at the code there. So here in the body, we have display grid and that's what's allowing us to create these columns and rows inside of it. We've created these columns where the first two columns, that's gonna be right here, one, five, nine and two, six, 10. This is 200 pixels wide and 100 pixels wide. Then this area right here with the three and the seven is getting an auto fit. So it's automatically taking up the existing rest of the space and then 25% of the width is what the four and the eight are doing inside of that column with that box of zooming. So that's where we get this sort of experience in the UI as we adjust the sizing. We're explicitly setting the grid and as I mentioned earlier, grid is not just horizontal but it's also vertical. So you can specify how the rows look as well. So here I have this grid template rows where I'm setting up the row template and so this first row is 25%, this second row is 100 pixels so I'm setting that specifically and then we have this auto on the bottom row and that auto is the most narrow here because it's just letting the content inside of it dictate how big it is. So we could change these values. If I made this 200, you would see that would quickly adjust here and that would be a much higher, a taller section there. We can increase percentages, we can use various unit types and we can also use justify content and align items within the grid just like you can do with Flexbox. I'm doing that right here within the boxes to center the numbers inside of them. So that's why as I change sizes, this five, six, seven, eight, they remain vertically and horizontally centered. I'm using a display grid within the box and I'm setting justify content center and align item center. So it works the same properties that we have with Flexbox, we can use in grid. You can also set up your grid as named grid areas. I love using emoji for this as they can represent a lot of information in one visual square unit. So here's what that can look like. In the HTML here, we only have four boxes which I'm going to be placing with grid named areas and you can see as I resize this, they also adjust in their size based on the width of the container which is the body in this case. So if we go into the CSS, we see that we have display grid on the body. We also are naming these template areas. One thing I forgot to mention in the last demo is this grid gap. Gap allows us to create spacing between elements. So you aren't hacking around, having margins and removing margins for the first and last elements and the ones on the right and left sides. This is true gap which is great because it's a feature that I've been hacking around for years. So now we can truly have gap. I can also increase the size of this gap so you can see where it's adjusting only between those elements but let's stick to 10 for the sake of this demo. So next we have these grid template areas and here I'm setting this entire first row to be just the header. Then the second row we have the main content taking up three quarters of the space, the sidebar taking up one quarter of the space and the footer taking up the entire bottom. When I'm placing these boxes into these named areas, I use grid area. So for box one, the grid area is header. For box two, that's main. For box three, that's the sidebar here and then for box four, that's the footer. So the way that these are readjusting is based on the fractional units of space that are left in this grid layout for them to be filled within. But we can specify that space. So we want that sidebar in the right to be a fixed value. Maybe we want it to be 150 pixels. Then we can create a grid template column. So we can have both grid template areas and a grid template column. So here I'm going to write grid template columns and I'm going to specify here, maybe I want this one fractional unit for those first three and then 150 pixels for that sidebar. So now as I'm resizing this page, the sidebar there, the third box remains fixed, but the other content is still resizing in those fractional units. There's a shortcut that also shipped with grid, that's the repeat function. So instead of writing one FR three times, I can write repeat three one FR and we get the same results here. So I'm just simply short handing this if you have a lot of items in your grid, maybe you have like a 12 by grid where you specify each column and you have things flowing into multiple columns like I have here with the footer, header and main. That really makes it a lot easier to write out these grid templates with this little shortcut. So we can also write out the rows. So I can write grid template rows. And then here I'm going to maybe make this auto 300 pixels and 100 pixels just to give it some dimension. So you could see how it's shifting in the space. We've now given some physical fixed space for that main area and sidebar in the footer. And then this header is taking the auto of the content within it, the automatic spacing, which is just right above this text value itself. Finally, we can make this look a little bit neater by using a single unit value. So instead of writing header, I'm just gonna command D to select all these. I can use a shorthand like H. For main, I'm just going to use letter M. For sidebar, I'm just gonna use an S. And then for footer here, I'm going to select this all and use an F. And this makes it really easy to see the entire grid and how it's laid out. And I think a fun way to do this also is to use emoji. So if I select right here, I'm just using the command tool to select all at the same time. I'm gonna hit backspace and then open up my emoji panel here. Maybe I wanna select a shoe to represent footer. So here I have an ice skate to represent the footer. So this totally works. And it's just a fun way to really represent the space that is really clear, like what you're looking at. It kind of gives you this mental shorthand. Maybe I want my main space to be what you're, you know, looking the most content. So the ta-da, why not? The sidebar, we could use arrows for this too. So I could use an arrow that points out. So it's like over here on the side. And then for the header, why not just use a little smiley right there? So I've selected all these. I'm opening up this template panel. And there we go, a smiley face is my header. So you can use emoji in your CSS. And I think it works particularly well in Grid because these are sort of single unit values that represent a lot of information. And it's a little bit more clear than just letters which you can forget what they mean. They could override other meanings. So I like seeing it all sort of laid out like this. Grid introduces a few new interesting capabilities that give even more options for building responsive designs. Here's an example of creating a responsive grid without the use of media queries like the example of Flexbox that media queries. In this demo, we're using the autofill keyword with a minmax function to create responsive boxes. We have 10 boxes here placed within the body which is where we're going to be creating our grid again. And so if we look at the CSS there, you can see that we have this grid template columns but we're using this autofill and a minmax function here. When I resize this page, you can see that these items are stretching until they hit a certain point and then they break to then display at a smaller size but with more items within that row. And so what we're doing here is we're in these columns specifying that the minimum size of these elements is 250 pixels. And when it gets smaller than that to break and then fill that space, one fractional unit of the remaining space. So if it hits 250, then we could add more items on the page and see it's saying 250. We can now have three items horizontally on the page within that row. So this is really cool because you are getting this responsiveness automatically. If I change this minimum size to 100 pixels, you'll see that more quickly we're filling up that space as we resize these values. Now what autofill does here is it fills the row with as many columns as it can. If they take up less space than allotted, then you'll see where that ends. So if I make this a much smaller value, say we set that to 40 pixels, as I stretch this out, you'll see that there is space on the right that it's not filling in. But if I change this to autofit, what's gonna happen is that's actually gonna stretch to fill the space regardless of what size that container is because we're telling it to stretch out. Autofit fits the columns into the row by stretching them so that they take up the full available space of the row. So this would be like if you applied the flex property, flex one to each of these children so that they would stretch to fit the space. Media queries, again, can be very useful when making multiple changes on a page. But flex and grid can provide their own macro and micro layout systems that adjust algorithmically and apart from specified media queries. Media queries do now go far beyond sizing alone. I wanna show you an example of using the prefers color scheme media query to showcase a dark theme on the web. In a previous episode, we talked about using custom properties for theming and we can use those same concepts and update those custom properties based on media queries. So remember this data tables demo where we have a data table example, this layout. So inside of our code, instead of adjusting these properties with JavaScript, I'm going to write a media query that says at media prefers color scheme dark. And so here we're updating the root properties just based on this prefers color scheme. So what does that look like? Well, right now we're seeing this light theme, but if I go into my system preferences on my computer, it's in general, I can change the appearance to dark and doing that will automatically change the color scheme here to the dark theme. And so we can do this all inside of our CSS. I've set up this media query here based on the color scheme preference. Responsive layouts help us build applications with user experiences more tailored to our customer's devices and personalized needs. I hope today's show helped you discover some of the ways that we can layout our applications and how responsive design extends past screen size alone. What are your favorite responsive experiences? Or what do you hope to see more of as technology gets more and more advanced on the web? Leave a comment below, we'd love to hear what you think. Until next time.