CSS Grid vs Flexbox: Which Is Best, When, And Why?

Jacinto Wong
Jacinto Wong
hero image

If you’ve been in web development for a little while, you’ve no doubt come across CSS Grid and Flexbox. Two tools that on paper, seem to do the same thing. However, there are specific differences between them.

Is one better than the other? Hmm well, it depends on the situation.

That’s why in this guide, I’ll break down each of these layout models, compare their strengths and limitations, and discuss their best use cases, so you can choose the right tool for your web projects.

Let’s get into it…

Mile-high overview and comparison

Want the answers right away?

Well as you probably guessed, there are pros and cons of each of these tools. Both are great in different scenarios.

I’ll break down both Flexbox and CSS Grid in more detail in just a second, but for now, here’s the mile high overview of each tool and when you should use them.

When to use Flexbox

Flexbox is best used for one-dimensional layouts, i.e. layouts that either go in a row or a column, but not both at the same time.

For example:

  • Navigation bars: Flexbox is perfect for horizontal navigation bars where menu items need to be spaced out evenly across a single row
  • Centering content: If you have a single column of items, like vertically aligning a series of cards or buttons in the center of a page, Flexbox makes it straightforward
  • Responsive layout adjustments: Flexbox is great for adjusting items in a row as screen sizes change. For instance, you might have a list of features that stack vertically on mobile but align horizontally on desktop. (More on this in a second)

Flexbox pros and cons

Pros:

  • Flexbox is excellent for 1D layouts (either in row or column)
  • It provides simple and effective alignment, distribution, and ordering facilities
  • Flexbox adjusts the size of the items based on the available space, which is great for responsive design
  • Excellent browser support

Cons:

  • Not suitable for complex 2D layouts, as it would require nested Flexbox containers
  • Gap control is not native; developers have to work around margins

When to use CSS Grid

On the other hand, CSS Grid is specifically designed for two-dimensional layouts, where you work with both rows and columns simultaneously. Thus, CSS Grid allows for more complex layout designs.

For example:

  • Grid layouts: CSS Grid is ideal for creating intricate web page layouts like a full-page magazine or blog layout, where you need to manage both rows and columns. You can place items into a grid structure with precise control over how they span multiple rows and columns
  • Dashboards: For data dashboards that require different widgets to be placed in a structured grid, CSS Grid provides the flexibility to arrange content dynamically
  • Image galleries: When creating a photo gallery, CSS Grid allows you to easily manage the placement of images into a uniform grid or a more artistic, asymmetric layout

CSS Grid pros and cons

Pros:

  • CSS Grid is perfect for 2D layouts (both columns and rows)
  • It can create complex layouts without nesting grid containers
  • It comes with gap control in the form of the grid-gap property
  • CSS Grid allows for fine control over the placement and sizing of elements

Cons:

  • CSS grid allows for more complex designs, but it’s overkill for simpler, 1D layouts
  • Browser compatibility is good, though not as widespread as Flexbox

TL;DR

So, as a general rule of thumb:

  • Use Flexbox when you need to control the layout in a single dimension - either a row or a column
  • Use CSS Grid when you want to control the layout in both rows and columns

However, don’t just take my word for it.

The more you understand each tool, the better you can make your own choices. So let’s break both of them down in more detail, as well as look at some other factors, such as layout control, and how they both handle complex or responsive designs.

What is Flexbox?

The Flexible Box Layout, (better known as Flexbox), is a CSS (Cascading Style Sheets) module designed specifically for creating flexible and responsive layout structures within a web page. More specifically, it helps you to align, distribute, and manipulate space among items inside a container.

However, Flexbox really shines when it comes to one-dimensional layouts - i.e. layouts that involve either a column or a row. (For those new to layout, columns go top and bottom and rows go left to right).

Sidenote: A great way to gain a better understanding of Flexbox if you’re new to it, is the free game Flexbox Froggy, which is an interactive set of challenges walking you through many different examples of how to use Flexbox.

Flexbox Froggy

Learning while playing is a great way to remember things. For example, these frogs are lined up in what is called a ‘reverse’ column. (It's a standard column, but the first item starts at the bottom, the 2nd item is above that, etc).

Anyways, back to Flexbox itself…

A crucial characteristic of Flexbox is its ability to adjust the width or height of items to fill available space in the best possible way based on set requirements. This feature makes Flexbox a fantastic tool for producing responsive designs with minimal effort.

Flexbox elements

There are two categories of Flexbox elements, they can either be Flex Containers or Flex Items:

How flexbox works
  • Flex Container: A flexbox container is simply an HTML element that has its display property set to flex or inline-flex. This property turns the container's children into flexible items. Once an element becomes a flex container, its immediate children become flex items, and the layout of these items is controlled by the flex container's properties
  • Flex Items: These are the children of a flex container. By default, flex items are laid out along the main axis of the flex container in a row, but their order, size, and alignment can be manipulated using various flex properties.

Let's break them down a little more.

Flex containers

Flex containers have two main axes: the main axis and the cross axis. The main axis is determined by the flex-direction property, and the cross axis is perpendicular to it.

For example:

  • flex-direction is set to row by default, meaning items will flow left to right, making the x-axis the main axis, with the y-axis being the cross-axis
  • Setting the flex-direction to column makes the items flow top to bottom, reversing the main and cross-axis orientations

Additionally, properties like justify-content and align-items are applied to the flex container but affect the alignment and distribution of flex items within it.

Flex items

As we said before, Flexbox items are the children of a flex container.

They can have their own dimensions (width and height), but these dimensions can be overridden or adjusted using flexbox properties.

Some of the key properties that can be applied to flex items include flex-grow, flex-shrink, and flex-basis, which control how flex items grow, shrink, and establish their initial size respectively.

For example

Here's a basic example of using Flexbox in CSS.

Flexbox example

And here's the code to create this:

    <div class="flex-container">
        <div class="flex-item">1</div>
        <div class="flex-item">2</div>
        <div class="flex-item">3</div>
        <div class="flex-item">4</div>
        <div class="flex-item">5</div>
        <div class="flex-item">6</div>
    </div>

```css
…

.flex-container {
    display: flex;
    width: 800px;
    height: 200px;
    …
    flex-direction: row; /* row, column, row-reverse, column-reverse */
    justify-content: center; /* start, end, center, space-between, space-around, space-evenly */
    align-items: center; /* start, end, center, stretch, baseline */
}

.flex-item {
    background-color: #007BFF;
    color: #ffffff;
    width: 50px;
    …
}

In this example, display: flex; makes it a flex container and turns the children into flex items.

While justify-content: center; is going to center items within the container on the main axis (horizontally), and align-items: start; aligns the items along the cross axis (vertically).

How Flexbox handles layout control and complex layouts

Flexbox excels in aligning items and ensuring predictable behavior in a row or column, as it allows you to control how items grow and shrink based on available space and manage their direction and order within a flex container.

However, Flexbox is less suited to complex layouts that require precise positioning across two dimensions.

Why?

Well, since Flexbox operates in one dimension at a time, creating intricate layouts often necessitates nesting flex containers. This nesting can then add complexity to your HTML and CSS, making it harder to manage.

So, for simpler, one-dimensional layouts, Flexbox is more intuitive and straightforward compared to CSS Grid. But for complex, two-dimensional positioning, CSS Grid would be a better choice.

How Flexbox handles responsive designs

Flexbox's ability to adjust the layout using flex-wrap makes it highly effective for responsive designs.

For example

Let’s say that you have a gallery with 6 images.

If the screen is large enough, it will show all of these images in one row. However, if the screen is smaller, (like on a mobile device or tablet), it will start to show less images in a row, and start aligning them in a column on its own.

Desktop

Flexbox desktop

Tablet

Flexbox on tablet

Mobile device

flexbox responsive design on mobile

The code to achieve this is actually quite simple also. (Obviously you would change it to your own image source).

<div class="gallery">
    <div class="image-box"><img src="https://source.unsplash.com/random?1" alt="Image 1"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?2" alt="Image 2"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?3" alt="Image 3"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?4" alt="Image 4"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?5" alt="Image 5"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?6" alt="Image 6"></div>
</div>

```css
.gallery {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}

.image-box {
    flex: 1;
    min-width: 200px;
    max-width: calc(100% - 10px);
    height: 200px;
}

.image-box img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

So what’s happening here?

Well, a few things:

  • The .gallery class is set to display: flex;, making its direct children, the .image-box elements, flex items
  • By adding flex-wrap: wrap; to the .gallery class, the layout adjusts responsively
  • When the combined width of .image-box elements exceeds the width of the .gallery container, the items wrap onto the next line
  • justify-content: center; ensures that flex items are horizontally centered within the .gallery container, while gap: 10px; adds a 10-pixel gap between each .image-box element, improving visual separation
  • Each .image-box element is given flexible properties with flex: 1;, allowing them to grow and shrink equally within the flex container. To control their width, min-width is set to 200 pixels, ensuring they maintain a minimum size, and max-width is calculated to prevent them from exceeding the container width by 10 pixels, creating a margin on the right side

So yeah, a fair few things!

Overall, the flex-wrap: wrap; property enables the responsive behavior of the image gallery, ensuring that the layout adjusts gracefully to different screen sizes by allowing items to wrap onto the next line when there's insufficient horizontal space.

Recap: When to use Flexbox

So as you can see, Flexbox is primarily designed for layout in a single dimension - either a row or a column. Therefore, it's ideal for smaller, reusable components and that's where this one-dimensional layout shines.

Flexbox is perfect for the following situations:

When alignment is key

With its properties like justify-content, align-items, align-self, etc., Flexbox gives you powerful alignment capabilities. This is very useful for components like navigation menus, footers, form fields, etc.

Flexbox alignment

When each child's size might vary

Flexbox allows children to flexibly grow and shrink. This makes it useful in components like image galleries, card grids, etc., where each child's size can vary based on content or screen size.

flexbox variable child size

When the order of items needs to change

With the order property, Flexbox allows you to control the order of elements visually, without changing the HTML. This comes in handy while creating responsive designs where the order of elements might need to change on different screen sizes.

We can see that when the screen size is larger than 600px, the main content is on the left side, because its order is set to 1 here.

Desktop layout

But, when it is less than 600px, the order is set to 2 putting it on the right side.

flexbox adjustable layout

Then, when it no longer fits, it will wrap so that both are in one column.

flexbox responsive layout
.container {
  display: flex;
  flex-wrap: wrap;
}

.sidebar { order: 1; }
.main { order: 2; }

@media screen and (min-width: 600px) {
  .sidebar { order: 2; }
  .main { order: 1; }
}

TL;DR

Flexbox makes it a lot easier to create layouts that look great on any device. It's an incredibly handy tool in modern web design, and being good at it can really set you apart.

That’s not to say that CSS Grid isn’t awesome also though…

What is CSS Grid?

CSS Grid is another layout system, but it’s designed specifically for creating two-dimensional layouts.

So, unlike Flexbox, which excels at arranging items in one dimension (either a row or a column), CSS Grid is inherently built for laying out items in rows and columns simultaneously, making it excellent for creating complex web design structures.

You can think of CSS Grid as the queen in chess. Just as the queen can move in any direction on the board, CSS Grid allows you to place content precisely where you want it within a grid of rows and columns.

This flexibility gives developers more control over the alignment, distribution, and spacing of content across both the horizontal and vertical axes.

flexbox vs css grid

In contrast, Flexbox is more like the castle (rook) in chess.

The castle moves in straight lines - either horizontally or vertically. Similarly, Flexbox excels in arranging items in one dimension, making it perfect for layouts that need to align items in a row or a column.

Sidenote: If you’re new to CSS Grid, just like Flexbox, there is another great interactive game called Grid Garden that works through multiple different examples to help you master all of the properties of CSS Grid.

Grid Garden

This time with carrots and not frogs!

Back to CSS Grid...

CSS Grid (just like Flexbox) also has Grid Containers and Grid Items that each have their own set of properties.

Grid containers

CSS Grid Grid Containers
  • A grid container is any HTML element whose display property is set to grid or inline-grid
  • Once an element becomes a grid container, it establishes a grid formatting context, allowing its direct children to participate in the grid layout
  • Grid containers can have both rows and columns, forming a two-dimensional grid structure
  • The properties applied to the grid container, such as grid-template-columns, grid-template-rows, and grid-gap, define the layout of the grid, including the size of its rows and columns, as well as the spacing between them
  • Grid containers offer extensive control over the positioning and alignment of grid items within the grid.

Grid items

CSS Grid Grid Items
  • Grid items are the direct children of grid containers
  • Each grid item occupies one or more cells within the grid, defined by the grid lines that form the rows and columns of the grid
  • Grid items can span multiple rows and columns, allowing for flexible and dynamic layouts
  • By default, grid items are placed in the order they appear in the HTML markup, but their position and alignment can be adjusted using grid-specific properties such as grid-column, grid-row, and grid-area
  • Additionally, grid items can be explicitly placed into specific grid tracks or areas, or they can be allowed to auto-place within the grid according to the grid auto-placement algorithm.

Let's take a look at a basic example of CSS Grid:

CSS Grid example
  <div class="container">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item">Item 5</div>
    <div class="item">Item 6</div>
  </div>

```css
    .container {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr; /* Three equal columns */
      grid-gap: 10px; /* Gap between grid items */
    }

    .item {
      background-color: #ff98db;
      color: white;
      padding: 20px;
      text-align: center;
    }

What's happening here?

In this example, the grid-template-columns property creates a grid with three columns of equal width.

  • The 1fr means "one fraction", or one part of the available space
  • The grid-gap property sets the gap between the grid cells. No matter what the size of the screen is, these items will stretch to fill the space and maintain the set gap of 10px.

How CSS Grid handles layout control

With CSS Grid, you can precisely position items in any location within your grid. It also allows you to overlap items, specify the order of items, and choose exactly where each item starts and ends.

This level of control is excellent for complex designs where precise positioning is needed.

For example

Imagine you are creating a page layout with a header, footer, two sidebars, and a main content area.

This kind of design is very straightforward with CSS Grid:

Page layout
.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: auto 1fr auto;
}

.header {
  grid-column: 1 / 4;
  grid-row: 1;
}

.sidebar-left {
  grid-column: 1;
  grid-row: 2;
}

.main {
  grid-column: 2;
  grid-row: 2;
}

.sidebar-right {
  grid-column: 3;
  grid-row: 2;
}

.footer {
  grid-column: 1 / 4;
  grid-row: 3;
}

CSS Grid and complex layouts

Complex layouts however are where CSS Grid truly shines.

It's perfect for defining the layout in two dimensions - rows and columns. Not only that, but you can place any item exactly where you want it within the grid and even layer items on top of each other for advanced effects.

For example

Here you can see a complex magazine layout using CSS Grid:

css grid magazine page example

In this example, we have a 12-column grid, and we can create items that span across different numbers of columns.


.container {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 20px;
}

.full-width {
  grid-column: 1 / -1;
}

.half-width {
  grid-column: span 6;
}

.one-third {
  grid-column: span 4;
}

.two-thirds {
  grid-column: span 8;
}

Although the layout is fairly complex, CSS Grid handles it well.

CSS Grid for responsive layouts

CSS Grid also provides fantastic responsive design capabilities.

The fr unit, auto-placement, and minmax function make creating responsive designs intuitive.

For example

Let’s look at the same example that we used with Flexbox earlier, where we have a page with a gallery of images.

In that gallery, we also have varying numbers of columns based on the screen size.

Desktop

CSS grid image gallery

Tablet

css grid tablet design

And mobile devices

CSS grid mobile responsive layout

CSS Grid can handle this just as well, however, you will notice that CSS Grid requires a little bit less code to make everything responsive:

<div class="gallery">
    <div class="image-box"><img src="https://source.unsplash.com/random?1" alt="Image 1"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?2" alt="Image 2"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?3" alt="Image 3"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?4" alt="Image 4"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?5" alt="Image 5"></div>
    <div class="image-box"><img src="https://source.unsplash.com/random?6" alt="Image 6"></div>
</div>

```css
.gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 10px;
}

.image-box {
    height: 200px;
}

.image-box img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

What’s happening here?

The repeat(auto-fill, minmax(200px, 1fr)); property creates as many 200px-wide columns as can fit in the container, with the remaining space distributed evenly.

Recap: When to use CSS Grid

CSS Grid is primarily designed for larger, two-dimensional layouts. It shines when you're working on the overall page layout or larger sections of it.

CSS Grid is perfect for the following situations:

When precise alignment is needed

If you need to align items precisely within both rows and columns, CSS Grid is your go-to tool. Its powerful alignment capabilities make it excellent for page layouts, grid-based designs, etc. Here is the relevant code:

precise aligment

When creating complex, responsive layouts

If your layout involves spanning items across multiple rows or columns, or creating complex responsive layouts, CSS Grid is the way to go.

Its grid-template-areas and grid-template-columns / grid-template-rows properties make such tasks relatively simple.

complex layouts with css grid

When dealing with overlapping content

CSS Grid also allows for items to overlap, giving you the power to layer items and control their stacking order. This can come in handy for designs with overlapping elements.

For example, if you are designing a portfolio website, you might want to overlay project descriptions on top of project images to create a modern and sleek presentation

overlapping design elements

So which should you use? CSS Grid or Flexbox?

Both Flexbox and CSS Grid play pivotal roles in modern web development, each with unique strengths tailored to specific types of layouts.

  • Flexbox is ideal for one-dimensional layouts, making it perfect for arranging items in a row or column. It excels in smaller, reusable components where alignment, distribution, and ordering are crucial
  • CSS Grid, on the other hand, is designed for two-dimensional layouts, managing both rows and columns simultaneously. It is excellent for larger, complex layouts requiring precise control over positioning

While CSS Grid provides more functionality for 2D layouts, Flexbox remains simpler and more intuitive for 1D layouts. Often, a combination of both is the most efficient approach. Flexbox is used for smaller, component-level layouts, while CSS Grid handles larger, page-level layouts.

It's important to note that one tool does not make the other obsolete. Instead, they complement each other perfectly. A modern web developer often finds themselves using both Flexbox and CSS Grid in a single project. By leveraging the strengths of both tools, you can create responsive, adaptable, and well-structured web pages.

Understanding when to use each tool is key to efficient web development. Flexbox simplifies the creation of one-dimensional layouts, while CSS Grid offers unparalleled control for complex, two-dimensional designs.

P.S.

I cover these tools and more, inside of my CSS course:

learn css this year

It takes you step-by-step from complete beginner to real mastery by learning modern and advanced CSS techniques. Plus you'll be building awesome real-world projects along the way to practice your skills and build your portfolio.

Check it out now if you want to learn more.

Not only is it up to date for 2024 (and updated every year), but you’ll also have access to me, as well as other students and other working web dev professionals inside of our private Discord community.


As an academy member, you also have access to every course in our library, so you can supplement your skills with advanced JavaScript projects and more!

More from Zero To Mastery

How To Become A Web Developer (From Complete Beginner to Hired) preview
How To Become A Web Developer (From Complete Beginner to Hired)

Want to become a Web Developer but not sure how? Our step-by-step guide shows you how to go from beginner to hired (without wasting $1,000s on a bootcamp or degree). And we answer all your FAQ.

CSS vs HTML: Comparison Guide (With Code Examples) preview
CSS vs HTML: Comparison Guide (With Code Examples)

HTML vs CSS. Learn their differences, pros, and cons, and how to use them with different variables for dynamic site creation!

Beginners Guide To Flexbox With Bootstrap preview
Popular
Beginners Guide To Flexbox With Bootstrap

Learn how to use Flexbox features for responsive design inside of Bootstrap. I've also included some code examples to show you how easy it is to start using!