✨ Create high-converting landing pages at scaleExplore the AI Landing Page Builder
Tech stack
·5 min read

CSS Flexbox vs Grid: Complete Guide & When to Use Each

For the longest time, layout systems in CSS were always a bit of a pain, as using tools like floats and tables was far from ideal. But, as these were the tools we had, we persevered. Then along came Flexbox and Grid, and the world of CSS layouts was changed forever by their ease of use and flexibility.

What is CSS Flexbox?

Flexbox is a powerful layout system designed for one-dimensional layouts. It helps us easily build responsive websites and elements.

Flexbox does this by allowing us to arrange items inside a container in either a horizontal (row) direction or a vertical (column) direction. Inside this container, we then have control over things like spacing, alignment, and order. For example, we can create a horizontal container with evenly spaced items using the code below.

<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>
.container {
	display: flex;
	justify-content: space-between;
	padding: 20px;
}

.item {
	background-color: green;
	padding: 20px 40px;
	text-align: center;
}

This code will then produce an output like the one below, with three items evenly spaced across the container.

Image of Flex Container

Try this Flexbox example on CodePen:

Configuring Flexbox

What we’ve looked at so far is a very basic example of Flexbox, but you can further configure it. Flexbox has a series of properties that you can use to control how it lays out your elements; however, some of the most commonly used are flex-direction, justify-content, align-items, and flex-wrap.

flex-direction

flex-direction, as you might have guessed, allows us to control the orientation in which the container displays its child items. As we mentioned earlier, this either has a default of row or column.

flex-direction: row | column;
An image of CSS Flex Direction

justify-content and align-items

When it comes to understanding justify-content and align-items, we first need to understand axes in Flexbox. There are two axes, the main axis and the cross axis.

The main axis is controlled by the flex-direction property. So, if we’re using flex-direction: row, the main axis is horizontal; if we’re using flex-direction: column, then it’s vertical.

The cross axis, as the name might suggest, is the axis that crosses the main axis. For flex-direction: row, the cross-axis would be vertical, and if we’re using flex-direction: column, then it would be horizontal.

Now that we understand axes in Flexbox, it’ll make understanding align-items and justify-content a lot simpler. Simply put, align-items controls the alignment of the items on the cross-axis. For example, if we use flex-direction: row, the cross-axis would be the vertical one. Therefore, align-items would place the items in the container at the top, middle, or bottom of the container along the vertical axis.

align-items: center | start | end;
Image of CSS align-items

justify-content, on the other hand, handles the alignment of the items inside the container along the main axis. So, if we’re using flex-direction: row, the main axis would be the horizontal one. Therefore, justify-content would place the items in the container at the start, middle, or end of the container along the horizontal axis.

justify-content: center | start | end | space-between | space-evenly | space-around;
An image of justify-content

flex-wrap

Finally, to round out the most common Flexbox properties, we have flex-wrap, which, as the name suggests, controls whether the items inside the container will wrap to a new line or not. By default, they won’t wrap and will try to all fit on one line.

flex-wrap: wrap | nowrap | wrap-reverse;
An image of CSS wrap

First time here? Discover what Prismic can do!

👋 Meet Prismic, your solution for creating performant websites! Developers, build with your preferred tech stack and deliver a visual page builder to marketers so they can quickly create on-brand pages independently!

What is CSS Grid?

Grid, like Flexbox, is another CSS layout system. However, unlike Flexbox, Grid operates on a 2-dimensional grid system, which enables us to easily place items in and across the various columns and rows we define within the grid. This means that Grid is the most powerful and flexible CSS layout tool available to us today.

To get started with Grid, you have to define a container that will house all the items inside it. To define this container, we apply the display: grid property to the container element.

Once we have defined our grid, we can start defining columns and rows using grid-template-columns and grid-template-rows. After the columns and rows are defined, we can start placing items inside them using grid-row and grid-column, or, for simplicity, we can use grid-template-areas to define areas on the grid and place items within them.

Here’s a look at a basic 3*3 grid of items, each placed in a different section of the grid.

<div class="grid">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item4">4</div>
  <div class="item item5">5</div>
</div>
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 150px);
  gap: 10px;
  grid-template-areas:
    "one one two"
    "three four two"
    "three five five";
  max-width: 600px;
  margin: auto;
}

.item {
  background-color: #deb841;
  color: white;
  font-size: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
}

.item1 { grid-area: one; }
.item2 { grid-area: two; }
.item3 { grid-area: three; }
.item4 { grid-area: four; }
.item5 { grid-area: five; }
An image of CSS grid overview

Try this Grid example on CodePen:

Configuring Grid

Much like Flexbox, Grid also has some unique properties we can use to configure how items are laid out inside the parent container. However, Grid also shares some properties with Flexbox, such as justify-content and align-items, which function similarly in both tools.

justify-items

justify-items is a Grid-specific configuration property that allows you to define the default justify-self for all the items inside the container. This means we can control how each item in the container aligns inside its own grid area.

justify-items: start | center | end;
An image of CSS justify-image

Subgrid

When it comes to configuring Grid, I wouldn’t be doing Grid justice if I didn’t mention the relatively new subgrid value for grid-template-columns and grid-template-rows.

Subgrid can be quite an in-depth topic to cover fully, and probably warrants its own post exploring it. But, by assigning subgrid as the value to one (or both) of the mentioned properties, we’re creating a nested grid inside the parent grid using the parent’s tracks.

In our example below, we have a parent grid that has three columns and three rows. We then define a subgrid with two rows and utilize the parent’s columns via the subgrid value passed to grid-template-columns.

<div class="grid">
  <div class="item">1</div>
  <div class="subgrid">
    <div class="subitem">2A</div>
    <div class="subitem">2B</div>
  </div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 150px);
  gap: 10px;
  max-width: 600px;
  margin: auto;
}

.item {
  background-color: #deb841;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  border-radius: 8px;
  padding: 10px;
  text-align: center;
}

.subgrid {
  display: grid;
  grid-template-rows: 1fr 1fr;
  grid-column: 2 / 4;
  grid-template-columns: subgrid;
  gap: 10px;
  background-color: #deb841;
}

.subitem {
  background-color: #774936;
  color: white;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
}
An image of CSS subgrid

Try this Subgrid example on CodePen:

As you can imagine, the subgrid value opens up numerous possibilities and further enhances the flexibility and power of Grid as a layout tool.

Learn more about subgrid.

Grid vs Flexbox

CSS Grid and Flexbox are similar in many ways, as we’ve seen, but they also have some differences. Here is a table summarising some of those differences.

Feature
Flexbox
Grid

Layout Axis

One-dimensional (row or column)

Two-dimensional (rows and columns)

Primary Use Case

Small-scale component layout (e.g. navbars, cards)

Large-scale page layout (e.g. templates, dashboards)

Item Placement

Based on source order (flow-driven)

Precise placement using grid lines or named grid areas

Learning Curve

Easy to learn

Steeper learning curve as it has a higher complexity

Layout Approach

Content-first: layout adapts to content

Container-first: define structure first, place content inside it

Overlapping Elements

Requires some “hacks” with margins and positioning to work

Can easily be done by adjusting the columns and rows the elements are placed in.

When to use them?

CSS Flexbox and Grid, as we’ve explored, share many similarities, which leads some developers to use them interchangeably. But this isn’t ideal, and there are scenarios where one excels over the other. So, when should you use them? Here is how I decide when to use Flexbox or Grid.

  • Flexbox => 1-dimensional layouts
  • Grid => 2-dimensional layouts

If I’m building a standalone component that only needs to control elements in one direction, like a navigation bar, then I’ll reach for Flexbox.

If I need to control the layout of elements in two directions, like placing that navigation bar on a page with other elements beside and below it, then I’ll reach for Grid.

Grid vs. Flexbox image

Best practices

To conclude this post, I wanted to share some best practices for working with Flexbox and Grid.

  1. Recognize when one tool is better suited for the job than another. If you find yourself creating more complex 2D layouts with Flexbox, it may be time to switch to Grid.
  2. Use Grid for macro-layouts (how elements fit on the page) and Flexbox for micro-layouts (how elements position their children).
  3. While it’s not always possible, plan your layouts in advance and determine where Grid or Flexbox will be most effectively used in your designs. A bit of preparation can go a long way.

In this post, we’ve looked at all things CSS Flexbox and Grid. What makes them similar, what makes them different, and ultimately, how to choose one over the other.

I hope you found this post helpful, and I encourage you to experiment with both layout methods and get to grips with them in your own projects so you can see their potential in action!

Thanks for reading.

Article written by

Coner Murphy

Fullstack web developer, freelancer, content creator, and indie hacker. Building SaaS products to profitability and creating content about tech & SaaS.

More posts
Coner Murphy profile picture.

Join the discussion

Hit your website goals

Websites success stories from the Prismic Community

How Arcadia is Telling a Consistent Brand Story

Read Case Study

How Evri Cut their Time to Ship

Read Case Study

How Pallyy Grew Daily Visitors from 500 to 10,000

Read Case Study

From Powder to Pixels - Perfectly Planned Ski Vacations, Now Perfectly Digital

Read Case Study