The CSS Grid Layout
In case you haven’t heard.
When getting started in web development, one of the first languages you’ll learn is the styling language CSS. You’ll use CSS for styling pretty much everything about a web page, but one of the more important parts you’ll use CSS for is the layout. And, right out of the box, CSS provides a few tools that will help you position and align the elements of your page.
Over the course of my development career, I’ve spent most of my time using only methods such as tables, floats, flexbox, position, and inline-block, but there was one method that I wasn’t all that familiar with — the CSS grid layout.
What does it do?
The CSS grid layout does just as the name suggests and then some; it provides you with an in-depth way to create configurable, two-dimensional grids using CSS. The layout was created to solve a few problems found with the other layouts (i.e. vertical alignment) and, as a result, offers a good deal of customization over each element of your grid. Having this ability to position and render each individual column, row, and cell goes a long way in successfully building pages to match different designs.
Terminology
Before building with the CSS grid layout, it is important to become familiar with the terminology, as it will help you understand the different properties and what they do.
- Grid Container:
The containing div of your grid items. - Grid Cell:
A grid cell is an individual cell of your grid, much like a table-cell. - Grid Column:
A grid column is a vertical row of grid items stacking horizontally. - Grid Row:
A grid row is a row of grid items spanning horizontally and stacking vertically. - Grid Area:
Any area on the grid bound by four grid lines. Can be a number of grid cells. - Grid Lines:
The horizontal and vertical lines that make up the grid. - Grid Tracks:
The spaces separating two cells of the grid.
The CSS grid layout offers two sets of properties; one for the container and one for the items in your grid.
Container Properties
When creating a grid, you’ll start with a containing div
and pass it the display
property in order to define it as a grid container. Depending on the type of grid you need, you have three values to choose from:
- Grid:
Used for block-level grids. - Inline-grid:
Used for inline-level grids. - Sub-grid:
Used for when the grid container is an item within another grid.
.container {
display: grid || inline-grid || sub-grid
}
Grid Columns and Rows
The containing div
has a handful of properties to configure the layout of your grid. By default, any children in the grid are stacked vertically into rows spanning the full width of the grid. The grid-template-columns
and grid-template-rows
properties are used to declare the basic layout.
The grid-template-columns
property specifies the number of columns and the widths of each column.
The grid-template-rows
property is similar to grid-template-columns
and specifies the number of rows and the heights of each row. Unless the row height is set, it will automatically take up the full height of the container.
Below, we declare three columns with a width of 100px
and three rows with a height of 100px
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
Additionally, you can use the fr
(fraction) unit to divide the entire width or height of the container by fractions. Here, we’ll divide it evenly with each column having a width of 1fr
and each row having a height of 1fr
.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
Now, if you add children to the container, the grid will fill each column with a grid cell.
<div class="container">
<div class="grid-cell">1</div>
<div class="grid-cell">2</div>
<div class="grid-cell">3</div>
<div class="grid-cell">4</div>
<div class="grid-cell">5</div>
<div class="grid-cell">6</div>
<div class="grid-cell">7</div>
<div class="grid-cell">8</div>
<div class="grid-cell">9</div>
</div>
For the sake of visibility, we’ll add a border to each cell and increase the font size.
.grid-cell {
border: 1px solid red;
font-size: 200%;
}
As is seen above, the grid cells will automatically align to the next row when the previous row is full.
One thing to keep in mind: since only three rows were declared with a height, any additional rows added with their original heights can be fixed by adding another row using the grid-template-rows
property.
Grid Areas:
The grid-template-areas
property can be used to define grid areas by name. Repeating an area name will cause that area to take up that many columns. If you want to leave a grid cell empty, use a period instead of naming an area.
Here, we specify that the area with the name top should span across the first row, that the area with the name middle should span across the second row, and that the area with the name bottom should span across the last row.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: 'top top top'
'middle middle middle'
'bottom bottom bottom';
}
Each grid cell must then be given a grid-area prop with the corresponding name of the area you want to appear.
<div class="container">
<div class="grid-cell top">1</div>
<div class="grid-cell middle">2</div>
<div class="grid-cell bottom">3</div>
</div>.grid-cell .top {
grid-area: top;
}.grid-cell .middle {
grid-area: middle;
}.grid-cell .bottom {
grid-area: bottom;
}
Grid Gaps
Spacing in-between the columns and rows can be added with the use of the grid-column-gap
and grid-row-gap
properties. To add spacing, just add the desired property to the grid container and specify the amount of space you want between each.
.container {
display: grid;
grid-row-gap: 10px;
grid-column-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
You can also use the shorthand grid-gap
to set the gaps at the same time. The first value passed in will set the row gap and the second will set the column gap. If no row gap is specified, however, then it will become the same value as the column gap.
.container {
display: grid;
grid-gap: 10px 10px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}
Justify and Align Items
The content within a grid can be aligned using the properties justify-items
and align-items
. Both align the content inside a grid item, but each to a different axis (row and column).
For aligning items along the row axis, you’ll want to use justify-items
.
You have four values to choose from:
- Start:
Aligns items to the start (left) of the grid area - End:
Aligns items to the end (right) of the grid area - Center:
Aligns items in the center of the grid area - Stretch:
Spans the whole width of the grid area (default)
.container {
justify-items: start || end || center || stretch;
}
For aligning items along the column axis, you’ll want to use align-items
. Like justify-items
, you have four values to choose from:
- Start:
Aligns items to the top of the grid area - End:
Aligns items to the bottom of the grid area - Center:
Aligns items in the center of the grid area - Stretch:
Spans the whole height of the grid area (default)
.container {
align-items: start || end || center || stretch;
}
Justify Content
In case your grid doesn’t take up the entire width of the grid container, you can use the justify-content
property. Using justify-content
set the alignment of your grid within its container to align along the row axis. You have seven values that can be passed in:
- Start:
Aligns the grid to the start (left) of the grid container - End:
Aligns the grid to the end (right) of the grid container - Center:
Aligns the grid to the center of the grid container - Stretch:
Resizes the grid to stretch the entire width of the grid container - Space-around:
Evenly spaces out the grid items while leaving half a space on each end - Space-between:
Evenly spaces out the grid items without leaving any spaces on the ends - Space-evenly:
Evenly spaces out the grid items with an equal space on each end
.container {
justify-content: start || end || center || space-around ||
space-around || space-between || space-evenly;
}
Child Properties
Grid Column and Row Positioning
Each grid cell can be positioned individually using a few properties. You can define specific grid lines of columns and rows you want the cell to align to by using the grid-column-start
and grid-column-end
properties for columns and grid-row-start
and grid-row-end
properties for rows.
grid-column-start
and grid-row-start
is the line that the item will begin on.
grid-column-end
and grid-row-end
is the line that the item will end on.
<div class="container">
<div class="grid-cell first">1</div>
<div class="grid-cell second">2</div>
<div class="grid-cell third">3</div>
<div class="grid-cell">4</div>
<div class="grid-cell">5</div>
<div class="grid-cell">6</div>
<div class="grid-cell">7</div>
<div class="grid-cell">8</div>
<div class="grid-cell">9</div>
</div>.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
}.first {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}.second {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}.third {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 3;
grid-row-end: 4;
}
Additionally, you can use the shorthand property of grid-column-start
and grid-column-end
called grid-column
. And similarly, the shorthand property for grid-row-start
and grid-row-end
, grid-row
.
Here, you can see the shorthand version of the same grid seen above
.first {
grid-column: 2;
grid-row: 1;
}.second {
grid-column: 2;
grid-row: 2;
}.third {
grid-column: 2;
grid-row: 3;
}
These properties can also be used to position a cell across multiple rows or columns and can even overlap other grid cells as long as both have their positions defined.
Here, we’ll position the first cell to span all three columns of the last row, the second cell to span the last two columns of the first two rows, and the third cell will span the first two columns of the first two rows.
.first {
border: 1px solid red;
grid-column: 1/4;
grid-row: 3;
}.second {
border: 1px solid blue;
grid-column: 2/4;
grid-row: 1/3;
}.third {
border: 1px solid green;
grid-column: 1/3;
grid-row: 1/3;
}
Justify and Align Self
Very similar to the container properties justify-items
and align-items
, each item can be aligned, but individually with the justify-self
and align-self
properties.
For aligning items along the row axis, you’ll want to use justify-self
. You have four values to choose from:
- Start:
Aligns the item to the start (left) of the grid area - End:
Aligns the item to the end (right) of the grid area - Center:
Aligns the item in the center of the grid area - Stretch:
Spans the whole width of the grid area (default)
.container {
justify-self: start || end || center || stretch;
}
For aligning items along the column axis, you’ll want to use align-self
. Like justify-self
, you have four values to choose from:
- Start:
Aligns items to the top of the grid area - End:
Aligns items to the bottom of the grid area - Center:
Aligns items in the center of the grid area - Stretch:
Spans the whole height of the grid area (default)
.container {
align-self: start || end || center || stretch;
}
Breakpoints
Because this grid layout is using CSS, customizing media queries to function in the desired manner without much hassle. You can rearrange your grid layout depending on the screen size by simply redefining certain properties.
Here we’ll start with a grid layout built for a smaller screen, so we’ll define two grid columns.
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
}
Using a media query, we can reconfigure the grid to expand to four columns instead of two when the screen has a minimum width of 768px.
@media (min-width: 768px) {
.container {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}
Browser Support
At the time of this article, most browsers support the CSS grid layout, but some may only support it partially. When it comes to desktop support, you’ll find the following browsers compatible:
- Chrome
- Firefox
- Safari
- IE 10 & 11 (partial support, requires
ms
prefix) - Edge (partial support, requires
ms
prefix) - Opera
On the mobile support front, you’ll find the following browsers compatible:
- iOS Safari
- Android Chrome
- Android Firefox
- IE 10 & 11 Mobile (partial support, requires
ms
prefix)
Final Thoughts
After spending some time working with it, one thing has become apparent; the CSS grid layout is quite useful for building out page structure and aligning the different pieces. The ability to configure each part of the grid makes the CSS grid layout a viable tool for building out a plethora of different layouts and is definitely worth looking into when thinking about building your next project!