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…
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.
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:
Pros:
Cons:
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:
Pros:
grid-gap
propertyCons:
So, as a general rule of thumb:
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.
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.
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.
There are two categories of Flexbox elements, they can either be Flex Containers or Flex Items:
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 propertiesLet's break them down a little more.
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-axisflex-direction
to column
makes the items flow top to bottom, reversing the main and cross-axis orientationsAdditionally, properties like justify-content
and align-items
are applied to the flex container but affect the alignment and distribution of flex items within it.
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.
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).
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.
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
Tablet
Mobile device
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;
}
Well, a few things:
.gallery
class is set to display: flex;
, making its direct children, the .image-box
elements, flex itemsflex-wrap: wrap;
to the .gallery
class, the layout adjusts responsively.image-box
elements exceeds the width of the .gallery
container, the items wrap onto the next linejustify-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.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 sideSo 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.
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:
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 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.
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.
But, when it is less than 600px, the order is set to 2 putting it on the right side.
Then, when it no longer fits, it will wrap so that both are in one column.
.container {
display: flex;
flex-wrap: wrap;
}
.sidebar { order: 1; }
.main { order: 2; }
@media screen and (min-width: 600px) {
.sidebar { order: 2; }
.main { order: 1; }
}
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…
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.
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.
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
or inline-grid
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 themgrid-column
, grid-row
, and grid-area
Let's take a look at a basic example of CSS Grid:
<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;
}
In this example, the grid-template-columns
property creates a grid with three columns of equal width.
1fr
means "one fraction", or one part of the available spacegrid-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.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:
.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;
}
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:
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 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
Tablet
And mobile devices
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;
}
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.
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:
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:
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.
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
Both Flexbox and CSS Grid play pivotal roles in modern web development, each with unique strengths tailored to specific types of layouts.
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.
I cover these tools and more, inside of my CSS course:
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!