CSS Grid Layout is a two-dimensional layout system for the web. It lets you lay content out in rows and columns. It has many features that make building complex layouts straightforward. This article will explain all you need to know to get started with grid layout.
.container{
display:grid;
}
What is a grid layout?
A grid is a collection of horizontal and vertical lines creating a pattern against which we can line up our design elements. They help us to create layouts in which our elements won't jump around or change width as we move from page to page, providing greater consistency on our websites.
A grid will typically have columns, rows, and then gaps between each row and column. The gaps are commonly referred to as gutters.
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
}
Creating your own grid in css
Having decided on the grid that your design needs, you can use CSS Grid Layout to create it. We'll look at the basic features of Grid Layout first and then explore how to create a simple grid system for your project.
The following video provides a nice visual explanation of using CSS Grid:
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
gap: 20px;
}
Defining a Grid
As a starting point, go to your editor and make an html file with a style tag for css code.
To define a grid we use the grid value of the display property. As with Flexbox, this enables Grid Layout; all of the direct children of the container become grid items. Add this to the CSS inside your file:
.container {
display: grid;
}
Unlike Flexbox, the items will not immediately look any different. Declaring display: grid gives you a one column grid, so your items will continue to display one below the other as they do in normal flow.
To see something that looks more grid-like, we'll need to add some columns to the grid. Let's add three 200-pixel columns. You can use any length unit or percentage to create these column tracks.
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
}
Now you should see three columns of equal width.
Uses of Grid
- Creating complex layouts: CSS Grid excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer, between parts of a control built from HTML primitives1
- Aligning elements: Like tables, grid layout enables an author to align elements into columns and rows1.
- Overlapping and layering: A grid container’s child elements could position themselves so they actually overlap and layer, similar to CSS positioned elements1
- Cleaner markup: CSS Grid makes your markup cleaner (in your HTML code) and gives you a lot more flexibility2. This is partly because you don’t have to change the markup (HTML code) to change the position of an item using the CSS grid2.
- Browser support: CSS Grid is easy to use and is supported by most web browsers2.
In addition to creating grids using lengths and percentages, we can use fr. The fr unit represents one fraction of the available space in the grid container to flexibly size grid rows and columns.
Change your track listing to the following definition, creating three 1fr tracks:
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
You now have flexible tracks. The fr unit distributes space proportionally. You can specify different positive values for your tracks like so:
.container {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
}
The first track gets 2fr of the available space and the other two tracks get 1fr, making the first track larger. You can mix fr units with fixed length units. In this case, the space needed for the fixed tracks is used up first before the remaining space is distributed to the other tracks.
Note: The fr unit distributes available space, not all space. Therefore, if one of your tracks has something large inside it, there will be less free space to share.
Gaps between tracks
To create gaps between tracks, we use the properties:
- column-gap for gaps between columns
- row-gap for gaps between rows
- gap as a shorthand for both
.container {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 20px;
}
These gaps can be any length unit or percentage, but not an fr unit.
Note: The gap properties (column-gap, row-gap and gap) used to be prefixed by grid-.
The spec has changed but the prefixed versions will be maintained as an alias.
To be on the safe side and make your code more bulletproof, you can add both properties:
.container {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
grid-gap: 20px;
gap: 20px;
}
Repeating Track Listings
You can repeat all or merely a section of your track listing using the CSS repeat() function. Change your track listing to the following:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
You'll now get three 1fr tracks just as before. The first value passed to the repeat() function specifies the number of times you want the listing to repeat, while the second value is a track listing, which may be one or more tracks that you want to repeat.
You can also use the repeat() function to create a grid with a repeating pattern of tracks. For example,
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
The repeat function can be helpful because:
- Concise and readable code: Using the repeat() function allows you to create grids with repeating patterns of tracks in a concise and readable way. This can make your code easier to understand and maintain.
- Flexibility: The repeat() function gives you a lot of flexibility when creating grids. You can specify the number of repetitions and the size of the tracks, and you can combine it with other track-sizing functions to create more complex layouts.
Implicit and Explicit Grid
We've only specified column tracks so far, yet rows are being created to hold our content. This is an example of the explicit versus the implicit grid.
The difference:
- Explicit Grid: Created using grid-template-columns or grid-template-rows.
- Implicit Grid: Extends the defined explicit grid when content is placed outside of that grid, such as into our rows by drawing additional grid lines.
Explicit:
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 100px 100px;
}
Implicit:
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.grid-item:nth-child(n+3) {
grid-column: 1 / -1;
}
By default, tracks created in the implicit grid are auto sized, which in general means that they're large enough to accommodate their content. If you wish to give implicit grid tracks a size, you can use the grid-auto-rows and grid-auto-columns properties. If you add grid-auto-rows with a value of 100px to your CSS, you'll see that those created rows are now 100 pixels tall.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
gap: 20px;
}
The minmax() function
Our 100-pixel tall tracks won't be very useful if we add content into those tracks that is taller than 100 pixels, in which case it would cause an overflow. It might be better to have tracks that are at least 100 pixels tall and can still expand if more content becomes added.
A fairly basic fact about the web is that you never really know how tall something is going to be — additional content or larger font sizes can cause problems with designs that attempt to be pixel perfect in every dimension.
The minmax() function lets us set a minimum and maximum size for a track, for example, minmax(100px, auto). The minimum size is 100 pixels, but the maximum is auto, which will expand to accommodate more content. Try changing grid-auto-rows to use a minmax value:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
gap: 20px;
}
If you add extra content, you'll see that the track expands to allow it to fit. Note that the expansion happens right along the row.
As many column as will fit
We can combine some of the lessons we've learned about track listing, repeat notation, and minmax() to create a useful pattern. Sometimes it's helpful to be able to ask grid to create as many columns as will fit into the container. We do this by setting the value of grid-template-columns using the repeat() function, but instead of passing in a number, pass in the keyword auto-fit. For the second parameter of the function we use minmax() with a minimum value equal to the minimum track size that we would like to have and a maximum of 1fr.
Try this in your file now using the CSS below:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: minmax(100px, auto);
gap: 20px;
}
This works because grid is creating as many 200-pixel columns as will fit into the container, then sharing whatever space is leftover among all the columns. The maximum is 1fr which, as we already know, distributes space evenly between tracks.
.container{
display:grid;
grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
grid-auto-rows: minmax(100px, auto);
gap: 20px;
}
Importance of all this
- Flexibility: The implicit and explicit grid allow you to create flexible layouts that can adapt to their content. You can define a fixed number of rows and columns using the explicit grid, or let the grid automatically generate rows and columns as needed using the implicit grid1
- Concise and readable code: The minmax() function allows you to specify a range of sizes for grid tracks, making your code more concise and readable. You can use it to create flexible layouts that can adapt to different screen sizes.
- Responsive design: The auto-fit keyword allows you to create responsive grids that automatically adjust the number of columns based on the available space. This makes it easy to create responsive layouts without having to use media queries3.
We now move on from creating a grid to placing things on the grid. Our grid always has lines — these are numbered beginning with 1 and relate to the writing mode of the document.
For example, column line 1 in English (written left-to-right) would be on the left-hand side of the grid and row line 1 at the top, while in Arabic (written right-to-left), column line 1 would be on the right-hand side.
We can arrange things in accordance with these lines by specifying the start and end line. We do this using the following properties:
- grid-column-start
- grid-column-end
- grid-row-start
- grid-row-end
These properties can all have a line number as their value. You can also use the shorthand properties:
- grid-column
- grid-row
These let you specify the start and end lines at once, separated by a forward slash /.
Download this file as a starting pointor see it live here. It has a defined grid and a simple article outlined. You can see that auto-placement is placing each item into its own cell on the grid.
Let's instead arrange all of the elements for our site by using the grid lines. Add the following rules to the bottom of your CSS:
header {
grid-column: 1 / 3;
grid-row: 1;
}
article {
grid-column: 2;
grid-row: 2;
}
aside {
grid-column: 1;
grid-row: 2;
}
footer {
grid-column: 1 / 3;
grid-row: 3;
}
Note: You can also use the value -1 to target the end column or row line, then count inwards from the end using negative values. Note also that lines count always from the edges of the explicit grid, not the implicit grid.
An alternative way to arrange items on your grid is to use the grid-template-areas property and give the various elements of your design a name.
Remove the line-based positioning from the last example (or re-download the file to have a fresh starting point) and add the following CSS.
.container {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 1fr 3fr;
gap: 20px;
}
header {
grid-area: header;
}
article {
grid-area: content;
}
aside {
grid-area: sidebar;
}
footer {
grid-area: footer;
}
Reload the page and you will see that your items have been placed just as before without us needing to use any line numbers!
The rules for grid-template-areas are as follows:
- You need to have every cell of the grid filled.
- To span across two cells, repeat the name.
- To leave a cell empty, use a . (period).
- Areas must be rectangular — for example, you can't have an L-shaped area.
- Areas can't be repeated in different locations.
You can play around with our layout, changing the footer to only sit underneath the article and the sidebar to span all the way down. This is a very nice way to describe a layout because it's clear just from looking at the CSS to know exactly what's happening.
Grid Frameworks in CSS
Grid "frameworks" tend to be based around 12 or 16-column grids. With CSS Grid, you don't need any third party tool to give you such a framework — it's already there in the spec.
Download the starting point file. This has a container with a 12-column grid defined and the same markup we used in the previous two examples. We can now use line-based placement to place our content on the 12-column grid.
header {
grid-column: 1 / 13;
grid-row: 1;
}
article {
grid-column: 4 / 13;
grid-row: 2;
}
aside {
grid-column: 1 / 4;
grid-row: 2;
}
footer {
grid-column: 1 / 13;
grid-row: 3;
}
If you use the Firefox Grid Inspector to overlay the grid lines on your design, you can see how our 12-column grid works.
Summary
Defining a grid container:
.grid-container {
display: grid;
grid-template-columns: 100px 100px 100px;
}
Placing items on the grid:
.grid-item {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
Creating a responsive layout
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}