Create a Responsive Layout with Flexbox

You can combine flexbox with media queries to create a layout that responds to different sized screens.

Media queries are commonly used in responsive designs in order to display a different layout to different devices, depending on their screen size. The reason for this is that certain layouts will always look too squashed (or even completely broken) when viewed on narrower screens.

For example, you can use media queries to display layout 1 to wide screens (desktops, laptops, etc), layout 2 to medium sized screens (tablets, large phones), and layout 3 to narrow screens (mobile phones, etc).

Here, we'll take the layout that we created previously, and add a media query to it so that it displays differently on smaller devices/viewports.

This example should be displaying all items stacked on top of each other. If not, you're probably viewing this on a really wide screen. In that case, reduce the size of your browser window until you see the layout collapse down.

Click the Preview button to view the example on a wider screen (this probably won't work if you're already viewing this on a mobile device).

In any case, here's what we added to the code:

All we did here was change display: flex to display: block.

We did this on the #main element so that its children are no longer flex items. This results in them stacking up on top of each other in source order.

But what if we didn't want the items to appear in source order? What if we want the navbar to appear before the article?

In that case, we could replace that change with another (just as simple) change. We could do this:

Here's what we did instead:

So now we have the navbar, the article, then the sidebar.

But you'll notice that the navbar and sidebar are taller than the previous example. How weird!

Actually, this is happening because of this piece of code:

Specifically, the bit that goes flex: 0 0 20vw is setting the flex-basis to 20vw, which is 20 percent of the viewport's width. We had previously applied this value for the width of the elements, but now that the flex-direction is column, it uses that value for their height.

If we only want the height to be based on the content, we could change this value to auto or remove the declaration altogether:

Mobile First

We could switch the code around so that our layout becomes a "mobile first" layout.

Mobile first is a term for layouts that are created primarily for mobile devices, but include a media query that changes the layout on larger devices. That's the opposite of what we did above, where our default layout was for large devices, and we added the media query for smaller devices.

So we can take the above example and modify it like this:

The layout still looks the same (which is good), but our media query now looks like this:

And all the other code comes before it.

Note that the media query uses min-width this time, to match all devices of that width and wider. In the previous example we used max-width to match only devices that were that width or narrower.

So what we've done is set the initial layout's flex-direction to column, then for larger devices, set it to row. We've also put the flex-basis back for the larger devices.