In the last lesson, we created a 12-column grid. In this case, all the elements in it could only be placed one after the other and had the width of one column. Of course, in real projects, this is a rare situation. Often, each element has its unique arrangement, and rarely do they stand just one after the other horizontally.
In one of the first lessons, we mentioned that all grid lines have ordinal numbers. Each grid line has two values:
- A number for counting from left to right
- A number for counting from right to left
And in the latter case, the numbers have a negative value. Let's see what it looks like on the example of a regular grid:
There are five vertical lines in this grid. The first line has two ordinal numbers: 1
and -5
. Also, there are four horizontal lines. The lowest of them has the ordinal numbers 4
and -1
.
We can use these numbers to bind elements to specific grid lines. Note that when using Grid we focus much less on notions like the width and heights of elements.
Now, we give these two characteristics away to the columns and rows. The size of the element inside the grid depends on them.
Let's go back to the example from the last lesson. We implemented a 12-column grid with three elements inside:
Now, we know the ordinal numbers of all grid lines and can place our elements in the following order:
- The first item will occupy 12 columns, starting with the grid line number 1. It'll take up two whole rows
- The second element should be located below the first element and will take up four columns, starting with the first
- The third element will occupy the remaining eight columns next to the second element
The result is a typical two-column layout structure. There are four properties in CSS Grid Layout for positioning elements along grid lines:
grid-column-start
— indicates the initial vertical Grid-line of the element's location.grid-column-end
— indicates the final vertical Grid-line of the element's location. Note that the value indicates before which column to place the item. The column specified in this property is not activated. You should add a new column to include the specified one. For example, you need to enter 13 for a 12-column layout to include the last columngrid-row-start
— indicates the initial horizontal grid line of the element's locationgrid-row-end
— indicates the final horizontal grid-line the property specifies before which row to place the element
Using these properties, we can achieve two goals:
- To set the initial positions from which we draw the element
- To set the final positions, which give us the width of the element
Let's set the necessary properties for all three blocks. Let's add some semantics:
Note that we set grid-column-start
for the header. It may seem redundant since the block already starts from the first column. It is true if no end grid line is specified. If you remove the grid-column-start
property, it's as if the element starts expanding from right to left instead of left to right:
We can make these properties more convenient because there are abbreviated ways to enter them. They allow you to write start and end values using just one property. The grid-column
property specifies the start and end strips horizontally. We use grid-row
to do the same vertically. The value is the start and end strip, separated by slash /.
If we use abbreviations, we can write the example above as follows:
.grid-header {
grid-column: 1 / 13;
grid-row: 1 / 3;
}
.grid-aside {
grid-column: 1 / 5;
grid-row: 3 / 13;
}
.grid-main {
grid-column: 5 / 13;
grid-row: 3 / 13
}
There is an interesting technique when positioning elements within strips is to use negative values. Since each strip has two values, we can also refer to them with negative values. It is especially useful when you want to stretch the item to the full width of the container. Instead of counting the number of strips, you can specify -1
as the final value. It will automatically stretch the item to the last strip. You no longer have to keep the number of strips in your head and change them when you change the grid.
As an example, let's stretch the header using a negative final value:
Keyword span
When we make layouts, it is often impractical to keep track of where an element starts and where it ends. It is much clearer to track:
- The starting strip from which we draw the element
- The number of columns it should occupy
It's impossible to do this with the tools we know.
To solve this problem, the developers introduced the span
keyword. It indicates the number of cells needed for the element when placed inside the grid. Now, instead of specifying the index of the strip where it should end, you can use this syntax: span <number of cells>
.
Let's continue working with the two-column layout. When creating the header, we used a negative value to determine the final strip. Let's move on to the two columns below. We can use the keyword span
to shorten the code and make it more understandable:
.grid-header {
grid-column: 1 / -1;
grid-row: 1 / span 2; /* Specify that the element occupies two columns vertically */
}
.grid-aside {
grid-column: 1 / span 4; /* Specify that the element occupies 4 columns horizontally */
grid-row: 3 / -1;
}
.grid-main {
grid-column: 5 / -1;
grid-row: 3 / -1
}
Moreover, you can use the keyword span
as a value. In this case, the browser will place the element with the number of lines/columns you specified. For example, the following will create a two-column wide element:
.col-2 {
grid-column: span 2;
}
It is useful when arranging elements within a grid. With this approach, it's possible to create your framework with classes responsible for the number of columns occupied by a block:
Naming lines
Also, for convenience and readability of your CSS, you can give names to your lines. These can be any names that describe a given line. As we go on, we will work using these names.
It is useful when creating complex layouts because it's not great to constantly remember where the different blocks start and end. The number of errors will increase as the layout becomes complex. In the case of names, everything is simpler, because they clearly describe the grid line with a name that makes sense to the developer.
To create named grid lines, use the following syntax for the grid-template-columns
and grid-template-rows
properties: [Line name] is the width of the strip after the line
. You can set any number of different names directly in the layout. It won't damage the current template.
Let's add named lines to our two-column layout to indicate the beginnings of each area. We use them to designate starting rows and columns. There will be four of these named lines:
header-top
— the topmost line from which we draw the site's headercontent-begin
— the line where the site's main content starts. In this case, it'saside
andmain
. It works great as a header height limitersidebar-begin
— the left line from whichaside
will be drawnmain-begin
— the line from whichmain
begins. Let's use it to limit the width ofaside
Let's substitute the names in the existing CSS and see how they are written:
.grid-12 {
display: grid;
grid-template-columns: [sidebar-begin] 1fr repeat(3, 1fr) [main-begin] 1fr repeat(7, 1fr);
grid-template-rows: [header-top] 1fr 1fr [content-begin] 1fr repeat(9, 1fr);
height: 100vh;
}
Let's parse the following line: grid-template-columns: [sidebar-begin] 1fr repeat(3, 1fr) [main-begin] 1fr repeat(7, 1fr);
. We can divide it into four parts:
[sidebar-begin] 1fr
. As described, we create a named line namedsidebar-begin
and a one-fraction-wide striprepeat(3, 1fr)
. One entry you've already seen will create three strips with a width of 1 fraction of each[main-begin] 1fr
. A named linemain-begin_ is created
The width of the strip after the line will be one fractionrepeat(7, 1fr)
. Seven strips with a width of one fraction each are created
We can use these names now in the grid-column-start
, grid-column-end
, grid-row-start
, and grid-row-end
properties we studied.
It's important to note that even if you name a line, it doesn't lose its index. You can refer to these lines by both their names and indexes (positive or negative).
Creating named grid areas
As well as naming grid lines, we can also name entire areas — sets of several strips connected by single grid lines.
So how can naming areas help with creating layouts? This tool is quite groundbreaking when it comes to creating designs in CSS. This property allows you to name the abstract areas and visualize the grid using those names. One of the disadvantages of this method is that it's a little unwieldy. Let's deal with this more when we do the practice tasks.
We use the grid-template-areas
property to create named areas. It takes data wrapped in double quotes as a value. The data in question describes the areas located on the grid. The more columns they occupy, the more times they need to be repeated inside the value. The values are separated by a space.
For the start, we create a grid of six columns. Put a two-column layout in it, as in the previous example. First, let's define the header. It takes up the entire screen width, so we allocate six columns.
Let's call this area, naturally, the header
. You can choose whatever name you like for this area. We also need to specify the block that will be the header
area. We do it using the grid-area
property, the value of which is the area name. In this case, it's header
:
.grid-6 {
display: grid;
grid-template-areas: "header header header header header header";
}
.grid-header {
grid-area: header;
}
Note that the .grid-6
container lacks the grid-template-columns
and grid-template-rows
properties. Their job is now the job of the grid-template-areas
role. When we specify a certain number of areas in it, we automatically create columns with a one-fraction width. If you need other values, you can always use the grid-template-columns
and grid-template-rows
properties to set the desired strip widths.
Now we've done the top row. It's time to start on the next row, where we'll place aside
and main
. To do this, continue to enter values in the grid-template-areas
property. Since we need a new row, we do not write inside the value with header
. Let's add a space and write new double quotes containing the locations of elements in the next row:
.grid-6 {
display: grid;
grid-template-areas: "header header header header header header" "aside aside main main main main";
}
.grid-header {
grid-area: header;
}
.grid-aside {
grid-area: aside;
}
.grid-main {
grid-area: main;
}
Note that the number of columns must be the same in each row. If you omit this point on any line, the browser will ignore the grid-template-areas
property because it can't understand or process what you want.
If more rows are needed, you can continue to add them. It is important if you have non-standard cell sizes. In other cases, we determine the height of blocks by the content within them. It is standard behavior, so you'll know it from designing layouts. In this case, we created a grid of 6 columns and two rows:
CSS allows you to move lines within a property to make it easier to read. It makes the grid-template-areas
property more visible. You can also put any number of spaces within the values themselves. We can set the columns in each row below each other:
.grid-6 {
display: grid;
grid-template-areas: "header header header header header header"
"aside aside main main main main";
}
There are situations when you need an empty cell instead of one of the columns. Since the number of columns in each row must be the same, you can't just delete one of the areas. Instead, grid-template-areas
can take a specific value that denotes an empty area. This value is a period — .
.
Let us make the header in the current grid one column smaller. It should take up five columns instead of six. In this case, the value of the property will look like this:
.grid-6 {
display: grid;
grid-template-areas: "header header header header header ."
"aside aside main main main main";
}
Do it yourself
Create a three-column layout consisting of the following:
- A header.
- A left sidebar.
- Main Content.
- A right sidebar.
- A footer.
Use both methods when creating. Use Grid-lines first, then Grid-areas. The number of columns in the grid is up to you. In this case, there can't be less than three.
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.