An interactive guide to Flexbox
joshwcomeau.com
joshwcomeau.com
I've been struggling with static documentation like the one from Tailwind [1] or MDN [2]. Writing good and intuitive documentation is hard, surely this must have been quite an effort.
[1]: https://tailwindcss.com/docs/flex-direction
[2]: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layou...
For CSS Grid, the equivalent resources would be https://css-tricks.com/snippets/css/complete-guide-grid/ and https://cssgridgarden.com/
These are all tutorial-level documentation. Once you've gone through those you can complement them with the MDN documentation on the individual properties as a reference.
Now I just need one for Grid.
CSS grid is heaps more complex than the flexbox spec, so I think the Grid Garden one is not quite as useful. But seriously – if anyone is just squinting when staring at flexbox stuff, go check out that game.
They have alignment properties for graphical elements that work like flex's justify-content and align-items properties so once you design a view in Penpot it becomes almost trivial to translate it into HTML/CSS using flex.
It really changed my mindset from working with relative or absolute positioning, blocks, margins, padding, etc... to simply working with flex everywhere. And it's responsive automatically!
I find CSS Grid easier to understand than Flex. I also think it's easier (arguably more logical) to start with Grid and then understand Flexbox and how fits in your Grid.
The problem is that popular frameworks like Bootstrap and Bulma still don't support CSS Grid (they use flexbox only for layout, although Bootstrap 5 has opt-in CSS Grid). You could argue that CSS Grid makes frameworks redundant for layouts only.
Developers have rightly complained how cumbersome CSS layout has been in the past. It's ironic CSS Grid is available in all modern browsers but developers still aren't using it.
Flex is better if the individual elements should have some control over the layout, whereas grid is better if the container should be fully controlling the layout.
Great 20min tutorial vid with examples and details on the above: https://www.youtube.com/watch?v=3elGSZSWTbM
You can nest flex such that it acts in a 2D way but it’s a bit annoying
Even the deconstructed pancake example in the posted article doesn't seem to be impossible with CSS grid but I haven't given it too much thought.
Another data point I use is that if I find myself adding a container for the sole purpose of layout, I realize that I should be using grid. That is one of the biggest wins of grid: you don't need to pollute your markup with nearly as many layout/presentation-only elements.
I guess I’m wondering why it’s any more complicated than:
* Flexbox is for formatting in one dimension (or axis)—a row or a column.
* Grid is for layout in 2-dimensions—columns and rows; a.k.a. a grid.
In fact, you can use flexbox and grid in the same layout, each doing its thing.
In fact, you can use flexbox and grid in the same layout, each doing its thing.
100% At 17:30 near the end of that video I linked is an example of mixing them.
Brilliant. The way basic CSS properties are taught often ignores the layout mode. Even MDN does not mention that "width" is a CSS property that is not always respected when "display: flex". Making this distinction more prominent would reduce the amount of confusion/frustration when certain CSS properties appear to "not work".
Flexbox has been great to work with because it's much easier to control your responsive design. You can choose what lengths stay fixed, which expand and shrink, etc.
When I learned how to use flexbox I went searching for how to add tools to my responsive-design toolbox. I learned about how to use media queries so that different CSS rules are applied based on the width of the page.
Flexbox, grid, and media queries are some of the heavy hitters in responsive design these days, but wanted to know more about effective use of things like CSS functions like calc, min, max, clamp, minmax (grid only) and when to use them. I can find reference material, but I haven't found any good resources that explain when you'd use them instead of something else.
Does anyone have a good resource for responsive design that covers use of CSS functions too? It's no good to have a tool in your toolbox if you don't know you should be using it.
MDN has some good explainers: https://developer.mozilla.org/en-US/docs/Web/CSS/clamp
Here I read the entire MDN article on clamp and it didn't click in my mind until you explained it.
Thanks to Flexbox and CSS Grid, you may not need media queries for most layouts.
But this site is helping a lot. Thank you.
CSS tricks has a very nice reference/guide: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The numbers displayed (855, 144, 144) don't match the widths actually shown, the calculations look the same across all three panels even though they have different parameters, and the displayed calculations (e.g. -619 + 1000 = 855) don't add up.
He is not wrong. It's an underrated improvement.
I couldn't believe it when gap arrived last year (2021) out of nowhere to solve the biggest issue I had with flexbox. No more assigning margins to flex items and dealing with the annoying side effect of that margin applying between item and container edge, rather than just between each item. CSS gap is applied on the flex container, and items can have zero margin, and everything just works now in flexbox.
I guess it’s time I drop IE11 support.
Unrelated but I was just wondering
“Content warning I make a food-related metaphor later in this tutorial.”
Why did the author have to include a content warning for food?
Make a taller-than-wide rectangle that always fills the maximum available space of the viewport without breaking aspect ratio. Inside have two elements: a square that always fills the max space while maintaining aspect ratio, and a rectangle that takes up all of whatever is left. Inside the inner square lay out 64 (or any n^2) elements as the tiles (like a chess board). No JS.
I’ve been fighting with flex and grid and aspect-ratio and getting into one of those rare moments where I feel viscerally angry. I think the main issue is aspect-ratio is a very very weak property.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
background: #999;
display: flex;
flex-direction: column;
align-items: center;
}
.tall-rectangle {
height: 100%;
aspect-ratio: 0.66;
display: flex;
flex-direction: column;
background: red;
}
.square {
background: black;
width: 100%;
aspect-ratio: 1;
display: flex;
flex-wrap: wrap;
}
.inner-rectangle {
background: green;
flex: 1;
}
.tile {
width: 12.5%;
height: 12.5%;
}
.tile.odd-row { background: black; }
.tile.odd-row.tile:nth-of-type(2n) { background: white; }
.tile.even-row { background: white; }
.tile.even-row.tile:nth-of-type(2n) { background: black; }
</style>
</head>
<body>
<div class="tall-rectangle">
<div class="square">
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div><div class="tile odd-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
<div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div><div class="tile even-row"></div>
</div>
<div class="inner-rectangle"></div>
</div>
</body>
</html>
For CSS grid, you can use the same HTML with the following styles: <style type="text/css">
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
background: #999;
display: grid;
grid-template-rows: 100%;
justify-content: center;
}
.tall-rectangle {
background: red;
height: 100%;
aspect-ratio: 0.66;
display: grid;
grid-auto-rows: auto 1fr;
}
.square {
background: black;
width: 100%;
aspect-ratio: 1;
display: grid;
grid-template-rows: repeat(8, 1fr);
grid-template-columns: repeat(8, 1fr);
}
.inner-rectangle {
background: green;
flex: 1;
}
.tile.odd-row { background: black; }
.tile.odd-row.tile:nth-of-type(2n) { background: white; }
.tile.even-row { background: white; }
.tile.even-row.tile:nth-of-type(2n) { background: black; }
</style>I think your solution is very close but breaks when I scale down the width of my viewport. If I set Chrome dev to iPhone 12 Pro or iPhone SE, for example, the chess board starts getting cut off.
Hmm... what would you like it to do in that case? Start shrinking the height? You can try adding `max-width: 100%` to the tall rectangle.
Yeah I think so. The idea is to fill as much of the viewport as possible but always maintain aspect ratio. Oh did I describe the challenge/problem poorly maybe? Sorry!
Still, you’ve gotten closer than I.
Don't get me started on links that aren't underlined blue font and only reveal themselves on mouse-over.
I know my UIs look bad. I've been in/around graphics/design/desktop publishing/etc for a long enough time to recognize it. I just don't know how to fix it. Now, I just make it functional enough to work, but never to a place that someone would ever think "this is good enough we don't need a designer involved".
Windows 11/Latest Chrome FWIW :-)
It doesn't appear to have an effect in this example because all of the text is the same size (and therefore, they do all share the same baseline). In the devtools, try bumping one of the items up to font-size: 2rem, and you'll see the effect it has.
My initial version of this post didn't have “baseline” as an option, since yeah it doesn't demonstrate it well, but I figured people would wonder why a single value was excluded.
Incidentally, baseline alignment is so handy, but I couldn't fit everything into this post. We cover it in more detail in my course (https://css-for-js.dev/)
It could be significantly simpler and, well, flexible:
https://terrainformatica.com/2018/12/11/10-years-of-flexboxi...
the only stupid thing is the "loop until there is no deviation", but I think it's not mandatory for most of the real-world layouts and one pass is enough.
the naming of those alignments is hard to remember, but that's it, it's not complex, it's just very unfortunate.
It is not that simple. In common case that's an LP task. It can be reduced to O(N) in some cases but in worst case it has polynomial time-complexity.
Grid does suffer from not being able to set min/max track sizes - like have a sidebar be say 20% of the width, but clamped between 200px and 300px
sidebar {
width:0.2*; //20% of the width
min-width: 200px;
max-width: 300px;
}You can do some neat things with the looping behaviour - like have a toolbar with some icons on the left and the right hand sides and a title centred in the toolbar - but then have the title move off centre as soon as the icons from either side touch it.
It is my understanding that flexbox was intended for 1D layouts and grid was intended for 2D layouts. We've been using grid for the overall page layout and flex inside certain regions.
Is there something I am missing here, or are we finding that the hammer is pretty good at screws too?
• Grid usage: https://caniuse.com/?search=css%20grid
• Flexbox usage: https://caniuse.com/?search=flexbox
I also think its general knowledge. Took a really long time for everyone to use Flexbox too. Even as late as 2016/2017 I saw engineers still reach for things like unsemantic[0] (the 960 Grid successor) and other utilities like it if they were doing custom layouts.
Grid is newer, and somewhat more complicated. Newer is probably the main reason it seems less popular than flex.
That's probably it. grid-template is a hell of a property too... Took me quite some time to figure it out.
And CSS grid is only working on pentalobe screws, until subgrid is usable.
I don't know what you mean by `mighty'
> you have to take know what to do if you want to behave like flexbox.
yes, as mentioned, that is if you want flexing. Most people don't want flexing - most layouts are static, grid-based and only change based upon media queries, where CSS grid is very similar.
Now, I'm not trying to be arrogant about it either.
This tutorial could have been 10 times better if Josh didn't pretend like what he wrote hasn't already been done (it has been, a million times, and I don't know why you'd keep beating this dead horse over and over again) - and instead made this same exact tutorial but actually built functional layouts in the process. You know, web pages that use Flexbox.
People don't learn by clicking on fancy buttons that rearrange some boxes in a specific order. People learn by example and by visually seeing the consequence of an action (in this case, the value of a property).
No offense meant at all to the author, of course.