How to center content with CSS Flexbox and CSS Grid
What you will learn
- What are the three modern ways to center content within a parent container using CSS?
- CSS Flexbox, CSS Grid, and CSS Grid with grid template areas.
- What are the assumptions made for the CSS containers in the blog post?
- The root container is the only direct child of the HTML body tag with base styling of 'margin: 0;' on the body element.
- How can you set up a root container as a Flexbox container?
- By adding 'display: flex;' to the container's CSS class.
- What CSS properties are used to center content within a CSS Grid container without using grid-template-areas?
- The properties are 'display: grid', 'justify-items: center', and 'align-items: center'.
- How does CSS Grid's 'grid-template-areas' property facilitate content centering?
- It allows for a declarative approach to layout, letting developers specify grid areas for content placement, enabling easy centering and repositioning with media queries.
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>
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;
}
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;
}
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;
}
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 with 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;
}
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;
}
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;
}
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 me on Twitter or LinkedIn!