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 own 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 2 values: a number for counting from left to right and a number for counting from right to left. And in the latter case, the numbers have a negative value. Let's see how it looks like on the example of a regular grid.
There are five vertical Grid-lines in this grid. The very first has two ordinal numbers: 1 and -5. There are 4 horizontal Grid-lines. The lowest one has the ordinal numbers 4 and -1.
These numbers can be used to bind elements to specific Grid-lines. Note that when using Grid we we focus much less on notions like the width and heights of elements. These two characteristics are now left 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, knowing the ordinal numbers of all Grid-lines place our elements in the following order:
The end result is a typical 2-column layout structure. There are four properties in CSS Grid Layout for positioning elements along Grid-lines:
grid-column-start
— ndicates 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. If you want to include the specified column as well, you need to add a new one. For example, for a 12-column layout, you need to enter 13 if you want to include the last column.grid-row-start
— indicates the initial horizontal Grid-line of the element's location.grid-row-end
— indicates the final horizontal Grid-line the property specifies before which row to place the element.Using these properties, we can not only set the initial positions from which the element is drawn, but also the final positions, which gives 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. This may seem superfluous, because the block starts from the first column. This 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.
In order to make these properties more convenient to use, there are abbreviated ways to enter them. They allow you to write start and end values using just one property. The grid-column
property is used to specify the start and end strip 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, the example above can be written 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
}
One interesting technique when positioning elements within strips is to use negative values. Since each strip has two values, it's also possible to refer to them with negative values. This 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. This 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.
When making layouts, it is often inconvenient to know which strip an element starts from, and from which one it ends. It's much better to know which strip the element is drawn from and the number of columns it should occupy. It's impossible to do this with the tools that we've studied so far.
To solve this problem, the developers of the standard introduced the keyword span, ndicating 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 set determine the final strip. Let's move on to the two columns below. Using the keyword span, it's possible 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
}
An interesting feature is that you can use keyword span on its own as a value. In this case, the browser will place the element with the number of lines/columns that you specified. For example, the following will create a 2-column wide element:
.col-2 {
grid-column: span 2;
}
This is useful when arranging elements within a grid. With this approach, it's possible to create your own framework, in which classes are responsible for the number of columns occupied by a block.
For convenience and to make it easier to read your CSS, in addition to using line indexes, you can give your lines names. These can be any names that describe a given line. As we go on, we'll be able to work using these names. This is useful when creating complex layouts, because it's not great to have to constantly remember where the different blocks start and end. The number of errors will increase as the layout becomes more complex. In the case of names, everything is much simpler, because they clearly describe the Grid-line with a name that makes sense to the developer.
In order 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, and you can do so 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:
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);
. It can be divided into four parts:
[sidebar-begin] 1fr
. As described, we create a named line named sidebar-begin and a one-fraction-wide strip.repeat(3, 1fr)
. One entry you've already seen, which will create 3 strips with a width of 1 fraction each.[main-begin] 1fr
. A named line main-begin is created. The width of the strip after the line will be 1 fraction.repeat(7, 1fr)
. Seven strips with a width of 1 fraction each are created.These names can now be used in the grid-column-start
, grid-column-end
, grid-row-start
and grid-row-end
properties that 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 both by their index (positive or negative) and by their names.
As well as allowing you to name Grid-lines the developers have also made it possible to name entire areas. As you remember, an area is several strips that are connected by single Grid-lines. So how can naming areas help with creating layouts? In fact, this tool is quite groundbreaking when it comes to creating designs in CSS. This property allows you not only to name abstract areas, but also to 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.
The grid-template-areas
property is used 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 themselves are separated by a space. Create a grid of 6 columns. Put a 2 column layout in it, as in the previous example. First, let's define the header. It takes up the entire width of the screen, so it needs to be allocated 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. This is done using the grid-area
property, the value of which is the name of the area. 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 .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. Specifying a certain number of areas in it automatically creates columns with a width of 1 fraction. 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, it makes no sense to 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: in each row, the number of columns must be the same. 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 from it.
If more rows are needed, you can continue to add them. This is important if you have non-standard cell sizes. In other cases, the height of blocks will be determined by the content within them. This is standard behavior, you'll know it already 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. This makes the grid-template-areas
property more visible. You can also put any number of spaces within the values themselves. The columns in each row can be set 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 instead of one of the columns you need some existing area, but an empty cell. 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 special value that denotes an empty area. This value is a period - .
. Let's make the header in the current grid one column smaller. The header should take up 5 columns instead of 6. 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";
}
Create a three-column layout consisting of the following:
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.
The Hexlet support team or other students will answer you.
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.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
Sign up or sign in
Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.