CSS Grid vs. Flexbox: Which Should You Use and When?

Both allow us to create complex layouts that were previously only possible by applying CSS hacks and/or JavaScript. Flexbox and CSS Grid share multiple similarities and many layouts can be solved with both. Let’s see if we can clarify when you should use Flexbox vs. Grid.

Industry recap

The CSS Grid vs. Flexbox debate is currently the hottest topic in the CSS community. If you follow industry news you will have seen many great articles appear lately, such as:

  • Rachel Andrew blogged on the question already back in 2016 and later continued discussing it in more detail.
  • In 2019, Chris Coyier started a viral Twitter thread that ended up in a longer article with some cool code examples on CSS-Tricks.
  • Michelle Barker also responded to Chris’ Twitter thread by authoring another excellent Grid vs. Flexbox article in her popular CSS {In Real Life} blog.
  • The MDN Community has created some thorough docs on the basic differences between Grid and Flexbox, which is currently the best available documentation on the subject.
  • An article by Geoff Graham discusses how the advancements in CSS, including Flexbox and Grid, have influenced modern CSS writing practices. It sheds light on the features that have had the most impact on current CSS approaches, offering insights into the ongoing evolution of CSS design and coding.

You can also find many other related blog posts, articles, videos, and discussions all over the web. As the topic is likely to stay relevant in the future, I’d recommend reading some of the articles above and developing your stance on the question, as nothing is set in stone yet.

Here’s another take.

One vs. two dimensions

The most important thing to know as you’re figuring out CSS Grid layouts vs. Flexbox, is that Flexbox is one-dimensional, while CSS Grid is two-dimensional. Flexbox lays out items along either the horizontal or the vertical axis, so you have to decide whether you want a row-based or a column-based layout.

The cross axis is always perpendicular to the main axis The cross axis is always perpendicular to the main axis The cross axis is always perpendicular to the main axis
The Flexbox cross axis is always perpendicular to the main axis. 

A flex layout can also wrap in multiple rows or columns and Flexbox treats each row or column as a separate entity, based on its content and the available space.

On the other hand, CSS Grid lets you work along two axes: horizontally and vertically. Grid allows you to create two-dimensional layouts where you can precisely place grid items into cells defined by rows and columns.

This is how W3C wants us to use Flexbox and Grid, however, practice frequently overrides theory, and not everyone is a fan of the one-dimensional vs. two-dimensional narrative. For instance, Chris Coyier made the following statement in his aforementioned article:

“I’m not the world’s biggest fan of the “1D” vs. “2D” differentiation of grid vs. flexbox, only because I find most of my day-to-day usage of grid is “1D” and it’s great for that. I wouldn’t want someone to think they have to use flexbox and not grid because grid is only when you need 2D. It is a strong distinction though that 2D layout is possible with grid though in ways it is not in flexbox.”

And, this is how CSS works in real life. We can create two-dimensional layouts with flexbox (due to its wrapping ability) and one-dimensional layouts with CSS Grid (due to its auto-placement ability), too.

Although Flexbox is originally not for building grids, it’s frequently used that way. The best example is Bootstrap 4’s grid system which is based on Flexbox. All Bootstrap 4 sites out there makes use of Flexbox to accomplish two-dimensional layouts, consisting of rows and columns. And, there are other popular tools such as Flexbox Grid that do the same.

When to use Flexbox vs. Grid

The most common misconception regarding CSS Grid layouts vs. Flexbox is that Grid is for full-page layouts and Flexbox is for smaller components. This is not the case at all. All the authors mentioned above warn against this approach, as it can seriously limit possibilities. You need to assess each layout individually on a case-by-case basis to pick the better option in CSS Flex vs. Grid.

Focus on content placement: CSS Grid

An important thing to note in the CSS Flex vs. Grid debate is that CSS Grid focuses on precise content placement. Each item is a grid cell, lined up along both a horizontal and a vertical axis. If you want to accurately control the position of items within a layout, CSS Grid is the way to go. The W3 docs of the Grid module assert:

“It provides a mechanism for authors to divide available space for layout into columns and rows using a set of predictable sizing behaviors. Authors can then precisely position and size the building block elements of their application into the grid areas defined by the intersections of these columns and rows.”

With Flexbox, it’s hard to predict behavior at certain viewports and you can get surprising results. Of course, you can set the widths and heights of flex items or make use of the calc() function but then you lose Flexbox’s main appeal: flexibility.

This is not the case with CSS Grid. It has properties such as grid-template-rows and grid-template-columns and utilities like the fraction unit that let you precisely calculate everything. Hence, Grid is especially suitable for creating unusual layouts like broken, asymmetrical, and overlapping layouts.

CSS Grid also makes it possible to create responsive layouts without using media queries. The idea comes from Heydon Pickering who recently published a YouTube video about algorithmic layouts. He introduces a simple Grid technique that makes grid cells wrap and adapt to any viewport sizes:

1
.container {
2
  display: grid;
3
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
4
  grid-gap: 1rem;
5
}

Although the layout wraps based on the available space, it’s still not content-aware like Flexbox, as the content inside the items doesn’t flexibly stretch out:

Focus on content flow: Flexbox

On the other side of Flexbox vs. Grid, Flexbox focuses on content flow rather than content placement. Widths (or heights) of flex items are determined by the content of the item. Flex items grow and shrink according to their inner content and the available space. This is how W3C’s flexbox docs explain the goals of the layout module:

“… (Flexbox) gains simple and powerful tools for distributing space and aligning content in ways that web apps and complex web pages often need.”

In short, Flexbox enables you to allocate space and align items flexibly, which is why it’s one of the main things to consider as you make a decision regarding CSS Grid layouts vs. Flexbox. Let’s see how Heydon’s grid would look like with Flexbox. The following code adds a margin of 0.5rem to each flex item (as Flexbox doesn’t have a gap property, we need to use the negative margin hack).

1
.container {
2
  display: flex;
3
  flex-wrap: wrap;
4
  margin: -0.5rem;
5
}
6
.item {
7
  margin: 0.5rem;
8
}

As you can see below, the first flex item with the long content stretches out as far as needed:

Of course, you can make fix-width flex items using the width or flex-basis properties. However, if you do so you lose flexbox’s content-awareness which is the main reason for its existence. You can also see above that flexbox treats each row independently. Different rows align flex items differently, based on the amount of text inside of them. There are no columns here and this is not a grid but a one-dimensional layout.

Flexbox also allows you to decide how your content should behave when there’s too much space or not enough space on the screen. I wrote about the topic in detail in my article about flexbox sizing. Using the flex-grow and flex-shrink properties, you can achieve a completely fluid layout that optimizes the allocation of flex items at every viewport size.

There are other typical use cases of Flexbox as well, such as centering items, adjusting the last item(s) of lists, sticking the footer to the bottom of the page, and creating responsive menus. You can find even more Flexbox usage examples in the MDN docs.

Browser support for Flexbox vs. CSS Grid

You should also consider browser support when thinking about CSS Flex vs. Grid. Flexbox has good browser support, while CSS Grid is not supported by IE11- and Edge 15-. 

CSS Flexible Box Layout Module (as of time of writing)CSS Flexible Box Layout Module (as of time of writing)CSS Flexible Box Layout Module (as of time of writing)
CSS Flexible Box Layout Module (as of time of writing)

CSS Grid Layout (as of time of writing)CSS Grid Layout (as of time of writing)CSS Grid Layout (as of time of writing)
CSS Grid Layout (as of time of writing)

When discussing Flexbox vs. Grid, articles frequently recommend using Flexbox as a fallback for CSS Grid. However, many developers consider it too much hassle and would rather create their layouts exclusively with Flexbox.

But Flexbox isn’t perfect, either. It has a couple of issues being collected in the Flexbugs repo on GitHub (with cross-browser workarounds for the bugs). If you bump into an issue while working with Flexbox it’s worth having a look at this list, as you might find the solution to your problem. It’s crucial to make the right choice between CSS Flex vs. Grid.