CSS Grid vs. Flexbox

Author:Texas Creative
Image

In the earlier days of front-end website development, many people relied on the CSS table structure to create layouts. Then, there were floats and other positioning methods, but these left out a lot of functionality and were essentially just hacks. Fortunately for me, I wasn't doing much front-end development in those days and was spared from (most of) the horrors.

In recent years, many developers, such as myself, have been utilizing Flexbox to help create more dynamic web page layouts. Flexbox has made things a lot easier for the front-end developers with vertical centering and aligning content with containers, but it's not quite the perfect solution either and it has plenty of its own quirks.

So, along comes CSS Grid Layout. It was implemented in Firefox and Chrome in March of this year, and by the end of summer, it was enabled by nearly all modern web browsers. CSS Grid can do many of the same things as Flexbox. Sometimes better, other times not so much. The goal of this article is to provide some clarity between the two and demonstrate some use cases.

The Dimensions

The first thing we need to understand is that Flexbox is one-dimensional, while CSS Grid is two-dimensional. Meaning Flexbox will be great for arranging content in a single direction, such as menu navigation buttons or links. It'll also require less code than CSS Grid.
However, if you're doing a full layout with rows and columns (two-dimensional), CSS Grid will be the way to go. The markup will be cleaner, the code will be easier to maintain, and you'll have a lot more flexibility.

The Terminology

If you're reading this blog, you probably have a decent grasp of Flexbox syntax and terminology, so I'll skip going over that. If you need a refresher, CSS Tricks has a great in-depth tutorial here.

Some of the terminology for Grid is similar, such as Grid Container and Grid Item. Here are some other important ones to note:

Grid Line: The dividing lines of the grid.
Grid Track: You can think of this as the rows or columns of the grid.  It is the space between two adjacent grid lines.

Most others mentioned in this article are self-explanatory, but here is another useful CSS Tricks article detailing everything if you’d like to learn more.  

One important thing to know is that Grid uses a new CSS unit, 'fr'. This unit is used to set the size of the grid track as a fraction of the free space inside the grid container. This free space is calculated after any non-flexible item.

.container {
  grid-template-columns: 1fr 20px 1fr 1fr;
}

The Uses

Let's say we want to build a page with a basic layout: a header, a footer, main content, and a sidebar menu.

First, let's start by building a basic DOM:

<div class="container">
  <header>Header</header>
  <main>Content</main>
  <aside>Sidebar</aside>
  <footer>Footer</footer>
</div>

Here's a basic example of what that will look like before adding any Flexbox or CSS Grid styling to it:

Now, as mentioned earlier, we'll start by focusing on the layout of the page.  We'll do this by adding the CSS Grid container to the main container of the page:

.container {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 1fr 3fr 1fr;
}

We'll place the items on the grid:

header {
  grid-column: span 6;
}
main {
  grid-column: span 4;
}
aside {
  grid-column-start: 5;
  grid-column: span 2;
}
footer {
  grid-column: span 6;
}

For the header, we'll want to use Flexbox to flow the content:

header {
  display: flex;
  flex-direction: row;
}

The final result should look like this:

I've added a grid overlay to help with the visualization of the Grid layout. As you can see, we have six even columns and five even rows. The content and sidebar sections take up three rows, while the header and footer take up only one. The items in the header are in their own Flexbox container, and are aligned in a row as such.

As you can see, using CSS Grid and Flexbox together results in cleaner more maintainable code. If we were to use only Grid or Flexbox, we’d end up with unnecessary containers in our DOM and a lot more CSS to compensate. Below is an example of how the DOM could look when building only with Flexbox:

<div class="container">
  <header>Header</header>
  <div class="inner-container">
    <main>Content</main>
    <aside>Sidebar</aside>
  </div>
  <footer>Footer</footer>
</div>

That's just a simplified example, but you can see that even without content we already have to add an extra container to align our inner elements in a different direction than the outer container.

The Conclusion

Flexbox and CSS Grid are both great, but neither one is a replacement for the other.  They are best used together to create clean, manageable, and flexible web pages. With almost full browser support, CSS Grid will be a necessary skill for front-end developers to learn and master.

As a TL;DR for you folks who skip straight to the end of a blog, here’s a quick recap of what was covered:

  • CSS Grid is best used for two-dimensional layouts, meaning columns and rows.  Think big picture, and overall layout of the page.
  • Flexbox works best in one-dimension (columns or rows).  Think individual content areas, such as a menu or sidebar.
  • There’s no reason to only use Grid or Flexbox exclusively.  They work best when used together, and doing such will leave you with much cleaner and maintainable code.
  • The new 'fr' unit makes the use of CSS Grid even easier, taking care of most of the responsive work by taking up a fraction of the space available in the container.

If you have any feedback or questions, leave a comment below. Be sure to check out our other Drupal and web development related blog posts as well.