CSS grid is another layout algorithm similar to Flexbox designed to ease User Interface design of websites and complex applications albeit with some subtle differences.
Unlike Flexbox which is single-axis oriented (the cross or main axis), grid layout is optimized for two-dimensional layouts, this means it allows grid items to be placed in arbitrary locations in the grid container. You can think of the CSS grid as a graph in mathematics.
Using CSS Grid the developer can transform the visually layout structure of the document without touching the markup because you can place grid item anywhere you want them in the grid container using grid specific properties.
The CSS Grid specification is quite technical and I will be using it sparingly in this post.
The following snippets will be used in this post with slight modifications along the way. Please save the snippets with the .html
and .css
extension respectively and make sure the CSS file is linked with the HTML. Remember all HTML snippets should be placed between the start and closing body
tag in your HTML.
<div class="parent">
<div class="child-1"></div>
<div class="child-2"></div>
<div class="child-3"></div>
<div class="child-4"></div>
<div class="child-5"></div>
<div class="child-6"></div>
</div>
.parent {
/* We will add stuff later */
}
/*
* We are using a attribute selector to select all
* child boxes
*/
[class ^= "child"] {
width: 100%; /* The width of the box */
height: 150px; /* The height of the box */
margin-right:0.5em; /* Some outer spacing to the right of the box */
margin-bottom: 0.5em; /* Some outer spacing to the bottom part of the box */
}
/*
* The child elements have been given colors so that
* we can tell them apart
*/
.child-1 {
background-color: tomato;
}
.child-2 {
background-color: #1560bd;
}
.child-3 {
background-color: #3eb489;
}
.child-4 {
background-color: #ffc40c;
}
.child-5 {
background-color: #da680f;
}
.child-6 {
background-color: #0a7e8c;
}
And kindly note that all screenshots are from Firefox 70 web browser and its Developer Tools.
With that out of the way. Let's Start.
Similar to Flexbox there are some key terminologies that'll help us get a bigger picture of the CSS Grid layout algorithm. These terminologies are theoretical concepts of CSS Grid and to really see the practical application we will mention some of the grid properties that make them possible.
GRID LAYOUT TERMINOLOGY
The following terms are associated with CSS Grid:
- Grid container
- Grid item
- Grid line
- Grid Cell
- Grid Track
- Grid Area
- Grid Gap
Grid container
A grid container is any element with its display
property set to the grid.
Update the .parent
CSS rule with the following:
.parent {
/* All other properties remain the same */
display: grid; /* Add this */
}
Load the HTML in your browser. You won't see any noticeable changes until you use the Developer Tools and check the Grid under the Layout tab then click the checkbox under Overlay Grid and hover your mouse over div.parent
.
Grid item
This is the direct first-level descendant element of a grid container and is automatically placed on the grid and you can also place each grid item at any location in the grid container.
The colored boxes in our code snippet are examples of grid items.
Grid line
Horizontal (row) or vertical (column) line separating the grid into sections.
Gridlines are referenced by number, starting and ending with the outer borders of the grid. Gridlines can also be named for easier reference as we'll see later
Update the .parent
CSS rule with the following and save your file:
.parent {
/* All other properties remain the same */
/*
* The following properties are just cosmetics
* that will enable us to see the grid lines
*/
width: 70%; /* Add this */
margin: 0 auto; /* Add this */
}
In the Developer Tools under Grid Display Settings click the checkbox Extend lines infinitely.
Now, click on "Display line numbers".
Grid cell
The grid cell is the intersection between a grid row and a grid column. This is similar to a cell in a table.
To see this in action we'll use a property named grid-template-columns
.
Update the .parent
CSS rule with the following:
.parent {
/* All other properties remain the same */
grid-template-columns: 50% 50%; /* Add this */
}
Save and refresh your browser.
In the previous code example we used percentages to set the column areas. CSS Grid defines an additional unit of measurement named the Fraction unit.
The Fraction unit or fr
represents a fraction of the available space in the grid container. It takes the total available space and distributes it in fractions. With this in mind we can rewrite our previous code as:
.parent {
/* All other properties remain the same */
grid-template-columns: 1fr 1fr; /* this will divide the grid into 2 columns */
}
Save your file and refresh your browser. You'll notice the output is the same.
As a takeaway, split the grid into three columns using the fr
unit. Your output should be similar to the image below.
There is another function that is used to control the size of rows and columns it is the minmax()
function and it's slightly more advanced. The minmax()
function allows us to declare the minimum and maximum width of a column.
Grid Track
The word "track" in CSS Grid terminology is either the row or column this means "Row tracks" are horizontal and "Column tracks" are vertical.
From the image below the "tomato" and the blue boxes is the Row track. The "tomato", green and brown boxes are the Column track.
Grid Area
The rectangular area between four specified grid lines. Grid areas can cover one or more cells. Using the grid-template-area
property on the grid container, grid areas allow us to define rectangular areas spanning one or more cells in the grid and give them a name. Then we can use those names to place items within the grid using the grid-area
property on grid items.
Now update the .parent
CSS rule to match the following:
.parent {
/* All other properties remain the same */
grid-template-columns: 1fr 2fr 1fr; /* This will split the grid into three columns */
grid-template-rows: auto 1fr; /* This will split the grid into two rows */
}
Up next, we need to specify the grid-template-areas
. The value that we'll supply to this property depends on the number of columns and rows we have in our grid. Let's see how it works.
.parent {
/* All other properties remain the same */
grid-template-areas:
/* column 1*/ /*column 2*/ /*column 3*/
/* row 1*/ "tomato tomato blue"
/* row 2*/ "yellow yellow blue";
}
Save your file and refresh the browser. Then click Display area names in the Developer Tools this will display the area names on each grid item.
The code snippet below will move the first box (tomato) to the "blue" area.
.child-1 {
/* All other properties remain the same */
grid-area: blue;
}
Save and refresh your browser.
We can also make child-3
span the yellow area.
.child-3 {
/* All other properties remain the same */
grid-area: yellow;
}
The result in the browser.
Grid Gap
This is the empty space between grid tracks and it is commonly called gutters.
Add the following to the .parent
CSS rule:
.parent {
/* All other properties remain the same */
grid-gap: 1.2em;
}
The result in the browser.
The grid-gap
has two other related properties for declaring row and column separately they are:
grid-column-gap
grip-row-gap
You can also supply two values to the grid-gap
and will serve as shorthand to the grid-column-gap
and grip-row-gap
. Take the example code below:
.grid-item {
grid-gap: 1em 2.2em;
}
PLACING ITEM ON THE GRID
One of the things that make CSS Grid such a powerful layout tool is it allows us to specify where on the grid any of the grid items should appear. Sounds awesome!.
The most basic ways for placing grid items on the grid is to declare the grid-column
and grid-row
values for each item. The grid-column
and grid-row
take values corresponding to the line on the grid.
Update your CSS by deleting the grid-gap
and grid-template-areas
from all child elements and .parent
then refresh your browser.
Your output should be similar to the image below. In the image, I have enabled the Display line numbers and the Developer Tools is docked to the bottom of the page.
Let's move .child-1
(the "tomato" colored box) from its current location to the bottom right corner of the grid.
To get started, we have to note the number of columns and rows. In our grid, it's evident that we have three columns and two rows.
First, we need to move the box to the third column:
.child-1 {
/* All other properties remain the same */
grid-column: 3;
}
Save and refresh your browser.
It is evident from the image above that we now have three rows this happens because when we moved the box to the third column, the other boxes were pushed down and they could no longer be accommodated in the grid so the browser had to create another grid line this line is called an implicit line.
An implicit line is a line created by the browser when we place an item outside the existing row or columns
With the box at its current location, we are halfway to our desired location, now we need to move the box to the second row. You might be wondering: Why the second row when we have three rows now?
Remember the third row is an implicit line created by the browser if the grid items can fit into the grid this line will no longer exist.
To move the box we'll make use of the grid-row
property with the new location of the box supplied as values. The location value have to be specified in a way that might seem strange to you but the comments in the CSS code should help you understand.
.child-1 {
/* All other properties remain the same */
grid-row: 2/3; /* This means row 2 column 3 */
}
Save and refresh your browser the box will be right we want it.
The following code snippet will move .child-2
to the second column in the second row.
.child-2 {
/* All other property remain the same */
grid-column: 2; /* Move to the second column */
grid-row: 2/2 /* Move to the second row and place in the second column */
}
The result in the browser.
We can also make a grid item span more than one column by specifying the start and ending locations. The location are separated by a slash as demonstrated when we explained grid-row
.
Now let's make child-3
span three columns.
.child-3 {
/* All other property remain the same */
grid-column: 1/4;
}
Save and refresh your browser.
So far we've used numbers to specify our grid lines but there is another way called Named lines.
Named lines serve as aliases to the column numbers declared in the grid container in our case the .parent
. The named lines are placed in square brackets before the template column values.
Add the following to the .parent
CSS rule:
.parent {
/* All other properties remain the same */
grid-template-columns: [line-one] 1fr [line-two] 2fr [line-three] 1fr [line-end];
}
Now let's move child-4
using the new named lines.
.child-4 {
/* All other properties remain the same */
grid-column: line-one/line-three; /* This is equivalent to grid-column: 1/3;*/
}
Save and refresh your browser. You will realize that .child-3
(the yellow box) will span three column and move back to its original position in the grid.
Mind you the last box is at the bottom because child-3
is spanning three columns at the top of the grid and child-4
is now spanning three columns as well which will push the boxes further away so the browser had to create an implicit line to accommodate the last box.
If you delete the grid-column
property and value of .child-3
and .child-4
the implicit line will cease to exist and the grid item will snap into their position.
There is also another keyword that you should be aware of and its called span
, we can use it in the grid-column
and grid-row
properties to indicate how many columns or rows a grid item should span. The syntax is straight forward:
.grid-item {
grid-column: 2 span; /* the grid item will span 2 columns */
}
.grid-item {
grid-column: 2/3 span; /* the grid item will span two columns from line 2 to 3 */
}
Go ahead and experiment with it.
In the next part, we'll pick up where we left off and discuss how we can align items in a CSS Grid.