DEV Community

Cover image for How to center content with CSS Flexbox and CSS Grid
Stephen Collins
Stephen Collins

Posted on • Updated on

How to center content with CSS Flexbox and CSS Grid

Introduction

Centering content with CSS can be frustrating for developers. With the advent of modern CSS layout models such as CSS Flexbox and CSS Grid, there's never been more ways to center content in a flexible, responsive way than now. In this blog post, we'll cover three modern ways to center a single child within a parent container, using CSS Flexbox, CSS Grid, and CSS Grid with grid template areas.

Assumptions

We're going to make some assumptions in creating all of our containers (for both CSS Grid and Flexbox) in this blog post, for the sake of simplicity and ease of trying out:

First assumption, our root container is the only direct child of the HTML body tag, so our html will look like this:

<html>
  <body>
    <!-- our root container -->
    <div class="container">
      <!-- our content to center -->
      <div class="content"></div>
    </div>
    </body>
  </html>
Enter fullscreen mode Exit fullscreen mode

Last assumption, we'll expect a base styling of margin: 0; on the body element. This allows our root container element (with proper handling of the width and height, in the following section) to take the entire viewport to then center content within, without an creating an overflow causing an unintended scroll effect:

body {
  margin: 0;
}
Enter fullscreen mode Exit fullscreen mode

With the assumptions out of the way, let's move on to centering content with Flexbox.

How to center content within a CSS Flexbox container

Before we can use flexbox to center content, we need to first create a Flexbox container.

.container {
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

With that one line of CSS, we have created a flexbox container for the elements with the container css class applied. By setting up the root most element of the body as a flex container, our entire layout can be based on Flexbox (it is simpler conceptually to have one main approach to handle layout with CSS). With the assumptions laid out in the previous section, let's add some additional CSS so we can use this container as the root of our entire app's layout:

.container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100vw;
  height: 100vh;
}
Enter fullscreen mode Exit fullscreen mode

Just a few CSS properties to explain. First the align-items CSS property. That CSS property handles how the children of the flex container should be handled according to the cross axis. The justify-content CSS property handles how children should be handled according to the main axis. So here, we are telling flexbox that we want both the main axis (through justify-content) and the cross (often considered as the "secondary" axis) axis (through align-items) center the content according to both axes - so if there is one child of this container, this child will be centered both horizontally (the default main axis of a flexbox container) and vertically (the cross axis).

As a side note, to change the primary axis direction from the default of the horizontal direction we can set flex-direction: column to make the vertical direction the main axis.

That's all we need to center content within a Flexbox container. I've made an example CodePen as a working example of using Flexbox to center content.

How to setup a CSS Grid container

Moving on to explaining how to center content with CSS Grid. Let's take a moment to understand the main differences between CSS Grid and CSS Flexbox. CSS Grid allows for responsive two dimensional layouts, versus CSS Flexbox's one dimenstion layout (the distinction between a main and cross axis). A neat illustration of this, is that with CSS Grid, not only can a layout adapt responsively from container width changes, but also container height changes. The way that CSS Grid is able to accomplish this two dimensional approach to layouts is through it's creation of grids (with rows and columns) managed by a given grid container for it's children. Every grid container child is called a grid item, and can be placed according to a given row and column.

This blog post will cover two approaches of centering content with CSS Grid, with and without grid-template-areas (Explanation of grid-template-areas in a later section).

First, without grid-template-areas. Just like with flexbox, we need to create a grid container first:

.container {
  display: grid;
}
Enter fullscreen mode Exit fullscreen mode

That sets up our grid container. Let's add just a few more properties:

.container {
  display: grid;
  width: 100vw;
  height: 100vh;
  justify-items: center;
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

Notice how we didn't specify how many rows (grid-template-rows) or how many columns (grid-template-columns) for this grid container to use. By default, we have one row and one column, thus one "grid cell". We are leveraging this fact, along with using justify-items and align-items, to center the content of the single grid cell, both horizontally and vertically. The child is then free to size itself, and it will be centered within the single cell of the grid.

This approach has a couple of drawbacks, and doesn't leverage the capabilities of CSS Grid like a better, slightly more involved approach, in the final section next.

How to center content within a CSS Grid container using grid template areas

Let's explain a much better solution for centering content with CSS Grid. Now, we will use CSS Grid's grid-template-areas property. One of the most awesome things about grid-template-areas is that we now have a truly declarative approach for building app-wide layouts. And - we can declaratively state how our layout should change when the container width changes (with media queries) and any all child grid areas can completely move all around the container, with a single CSS property change and without needing additional markup. See our blog post here on using media queries with grid template areas.

To start with centering content with CSS Grid's grid-template-areas, let's first begin with what the container and content CSS classes should look like:

.container {
  display: grid;
  width: 100vw;
  height: 100vh;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
  grid-template-areas:
    ".    .    ."
    ". content ."
    ".    .    ."
}

.content {
  grid-area: content;
}
Enter fullscreen mode Exit fullscreen mode

Like before, display: grid; creates a grid container, and width: 100vw; and height: 100vh; tells the container to expand to the full size of the viewport.

Here's the cool new stuff: grid-template-rows, grid-template-columns and grid-template-areas. The grid-template-rows tells the container how many rows it should create, and the size of each row. 1fr is a unit that basically says to use all the available space relatively. So, with repeat(3, 1fr); we are saying we want three rows, and make each row expand equally (so they each are equal in width). The grid-template-columns is the exact same as the grid-template-columns but for columns.

The grid-template-areas property is what makes this layout approach with CSS Grid declarative. Three rows, each marked by " ", and then three columns, each with an identifier for the specified grid area (either a ., which states to set this given grid cell as "empty", meaning don't put any grid area in this grid cell, or content) says that regardless of the order that the children of the grid container are set in the actual HTML, position them according to the grid-template-areas property value within this grid container. Illustrating this approach using grid-template-areas here with this CodePen. This is really powerful - you can put any child grid item anywhere in the grid, and completely rearrange them however with using media queries (or even with JavaScript). Cool stuff!

Conclusion

We've covered in this blog post multiple approaches to centering content with both CSS Flexbox and CSS Grid, along with demonstrations in CodePens here with Flexbox, here without grid-template-areas and here with grid-template-areas. Questions or input? Feel free to connect with us on Twitter!

Top comments (0)