Introduction to CSS3 Grid Layout. We work with grids
- Tutorial
Update: Some of the information in this article is outdated. I recommend fresh materials on css-live.ru .

The CSS3 module Grid Layout is one of the most interesting, in my opinion, modules in the CSS3 family. The official history of the module in the form of a draft specification totals today a little less than a year. Vladimir Yunev wrote about the preliminary announcement with the name CSS Grid Alignment at TPAC 2010 in December 2010. It should also be noted that with a slightly different name and somewhat different syntax, but with the same essence, it was declared as WD back in 2007. Today, module development work is in full swing, preliminary implementation is already in Internet Explorer 10, and there is hope that support for new features will also appear in future versions of other popular browsers.
The task that the CSS3 Grid Layout model solves is very simple and understandable to any web typesetter (and not only him): to provide a convenient mechanism for arranging content on a virtual grid.
Unlike the old table-based approaches based on the use of table, the semantics of the document are not cluttered here and the presentation is clearly separated from the content. In contrast to various variations of block layout with insane and multi-story floats, becoming with an somehow complicated structure, combined with manually calculated indents, here the description of styles becomes trivially simple and transparent. Unlike absolute positioning with reference to coordinates, flexibility remains here. Unlike the css / js libraries that are popular today for grid marking by specifying the appropriate classes (take at least the samebootstrap or yui css grids ), class binding is not cluttered here.
Sheer pleasure! It remains only to wait for wide support :) However, if you plan to make Metro-style applications for Windows 8 on html / js, the key features described in the CSS3 Grid Layout module are already working - and you can move forward using convenient and practical mechanisms.
To quickly understand how Grid Layout works, let's start with an example right away. Imagine that you need to solve the classical task of layout of a three-column layout with approximately the following contents:
which needs to be divided into three columns like this:

This is a classic task, so I will not dwell on how it is solved in the case of using traditional approaches for multi-column block layout. Let's see what can be done using the Grid Layout (I skip the browser prefixes in the examples, however, in practice they need to be added - for IE it's -ms- ).
Here is a sample CSS code:
In the simplest case, all that needs to be done is to indicate in the container (section) that the contents inside it should be arranged on a grid and set a virtual grid using the grid-columns and grid-rows properties (I’ll talk about what values they take). Further for each element inside it is enough to say where it should be located.

And it's all! Total:
Now let's understand the details and additional features.
To create a virtual grid, along which elements will be further placed, it is necessary to describe the grid tracks (Grid Tracks) - rows and columns inside the grid:
Tracks are located between the grid lines (Grid Lines), which, in turn, are located on the right-left and top-bottom of each track:

To specify how the element will be placed on the grid, you need to indicate which line vertically and horizontally will be attached:

By default, an element takes up space from the specified line to the next (therefore, such numbering coincides with cell numbering and everything looks as if we are talking in which cell to place the element).
To stretch an element over several grid cells, you can use the grid-row-span and grid-column-span properties :

By default, both properties are set to 1, which corresponds to stretching the available space from the specified line to the next (+1).
It often happens that the grid intended for use contains some characteristic pattern:

It would be convenient to describe such grids in a more compact and transparent form - and there is such an opportunity! The example above can be described as follows:
The pattern itself is described in parentheses, after which the number of repetitions is indicated in square brackets.
===
Now that we know the basic possibilities for describing grid lines, let's go back to the tracks and try to deal with the units used.
As you can see above, in places I used an unusual value when specifying the sizes of some columns and rows - 1fr. We will talk about this and other possible values when specifying the length.
When describing the width of the columns and the height of the lines (track sizes), the following units and values can be used:
Let's try to figure out how fraction values work. The grid takes up some space in width and height. It may depend on the content, be rigidly fixed, or occupy all available space in an external container. Further, when describing the tracks of a part of columns and lines, you can explicitly set what size they should be, for another part you can indicate that their length depends on the content.
Now, if you subtract the sum of all such explicit or “content” lengths from the available length allocated for the grid vertically or horizontally, the remaining space is distributed between the remaining tracks in proportion to the proportions indicated in them (the size of the fraction divided by the sum of all such shares):

In the example above, these are three columns with widths in the ratio 2: 1: 1 and two rows with heights in the ratio 5: 2.
The draft specification provides such a comprehensive example that allows you to see this whole scheme with different types of values at once:
Here the following lines are defined (tracks, they are columns in this case):
There is still a small nuance regarding the accounting for shares that were inside the minmax function: they are taken into account in the total amount of shares only if indicated in the maximum position. Shares indicated in the minimum position are considered equal to 0px. For more details on the calculation, see the specification.
===
The next step is to try to figure out how the elements are placed between the grid lines (inside the cells).
Now that the elements are “tied” to the grid lines, a natural question arises: how are they located between the lines?

The binding of elements to the cell borders is controlled using the grid-column-align and grid-row-align properties . The following values can be used for control:
I think the actions are obvious from the name, I only note that in each case we are talking about positioning an element according to its margin box. The default value is stretch.

The anchor in the columns (horizontally) corresponds to the direction of the text (for example, in Arabic, start will be on the right and end will be on the left). The snapping in rows (vertically) coincides with the direction of the flow of blocks (this, by the way, means that in some East Asian languages, rows and columns can swap places).
The next important point: the arrangement of elements inside the grid with overlays. What happens if, for example, two elements are attached to the same lines, or are superimposed when expanding to several cells?
First of all, it is important to understand the following nuance: the elements placed inside the grid do not directly affect the location of each other. If you tie ten elements, say, to the second line horizontally and the third line vertically, then by default they will all be placed one on top of the other, as if each of them is tied to the corresponding corner. Elements can only affect the size of the tracks, if they are tied, in turn, to the size of the content.

To control the display order of such layers, the current version of the specification expands the capabilities of z-index, allowing you to control the layers of elements inside the grid.
Note : in the previous version of the specification, based on the current version of IE10 (platform preview 5), a separate grid-layer property was defined for these purposes , so as not to conflict with z-index, however, later in the discussion in the working group this solution was revised.
Usage example:

To start working with grids in browsers (not yet) supporting the CSS Grid Layout module, you can use the eCSStender js library and the CSS3 Grid Alignment extension , which support the following properties:
An example of work can be found here .
Finally, let's slightly open the door to the future and take a look at what other possibilities are being prepared in the CSS3 Grid Layout module .
Please note that for today the features mentioned below are only described in the draft specification, but do not yet have support among released browsers (including pre-release versions). They may also change in the future depending on the community reaction and recommendations of the CSS working group.
Optionally, to snap an element to the grid, you can specify not only the start, but also the end line.

Unlike the span mechanism, which says how many cells an element should stretch horizontally or vertically, this feature allows you to clearly indicate on which line the element should end. It is also convenient to use in combination with the ability to name individual grid lines.
For convenience, the lines can be given names. This is done by inserting string values in the corresponding places in the description of the tracks (you can give several names if this makes practical sense, for example, in terms of markup semantics):
Further, when describing element binding, you can refer to these names:

The specification also introduces 4 pre-named lines - vertical and horizontal start and end , in fact, framing the entire grid. This allows, for example, to position the element "from the second column to the last", without thinking about the total number of columns.

Another way to place elements on a grid is to use templates to describe the virtual structure of blocks:

At the same time, to place an element with a buckle to one or another virtual cell, it is enough to refer to it with the corresponding rule:
This approach is especially convenient if, depending on various conditions, for example, screen resolution, you need to change the arrangement of elements and even redo the grid itself. In a similar situation, Grid Layout goes well with Media Queries:

Note that the binding of the article itself to the named cell does not change. (Pens are already itching to start using, however, we are waiting for it to be implemented in browsers.)
Я постарался дать в статье обзор ключевых возможностей модуля CSS3 Grid Layout. Надеюсь, они вдохновляют вас не менее, чем меня. :)
Напомню, что модуль продолжает развиваться, редакторы собирают отзывы от внешнего сообщества и внутри рабочей группы CSS. На действующую реализацию основного функционала можно посмотреть в Internet Explorer 10. Несколько интересных примеров можно найти на ietestdrive.com: The Grid System и Hands On: CSS3 Grid Layout:

Также еще раз отмечу, что возможности Grid Layout, уже поддерживаемые движком IE10, также можно использовать при разработке приложений в стиле Metro на HTML/JS для Windows 8.
Introduction

The CSS3 module Grid Layout is one of the most interesting, in my opinion, modules in the CSS3 family. The official history of the module in the form of a draft specification totals today a little less than a year. Vladimir Yunev wrote about the preliminary announcement with the name CSS Grid Alignment at TPAC 2010 in December 2010. It should also be noted that with a slightly different name and somewhat different syntax, but with the same essence, it was declared as WD back in 2007. Today, module development work is in full swing, preliminary implementation is already in Internet Explorer 10, and there is hope that support for new features will also appear in future versions of other popular browsers.
Why do I need a grid layout?
The task that the CSS3 Grid Layout model solves is very simple and understandable to any web typesetter (and not only him): to provide a convenient mechanism for arranging content on a virtual grid.
Unlike the old table-based approaches based on the use of table, the semantics of the document are not cluttered here and the presentation is clearly separated from the content. In contrast to various variations of block layout with insane and multi-story floats, becoming with an somehow complicated structure, combined with manually calculated indents, here the description of styles becomes trivially simple and transparent. Unlike absolute positioning with reference to coordinates, flexibility remains here. Unlike the css / js libraries that are popular today for grid marking by specifying the appropriate classes (take at least the samebootstrap or yui css grids ), class binding is not cluttered here.
Sheer pleasure! It remains only to wait for wide support :) However, if you plan to make Metro-style applications for Windows 8 on html / js, the key features described in the CSS3 Grid Layout module are already working - and you can move forward using convenient and practical mechanisms.
The basics
To quickly understand how Grid Layout works, let's start with an example right away. Imagine that you need to solve the classical task of layout of a three-column layout with approximately the following contents:
Title Content which needs to be divided into three columns like this:

This is a classic task, so I will not dwell on how it is solved in the case of using traditional approaches for multi-column block layout. Let's see what can be done using the Grid Layout (I skip the browser prefixes in the examples, however, in practice they need to be added - for IE it's -ms- ).
Here is a sample CSS code:
section {
display: grid;
grid-columns: 150px 1fr 200px;
grid-rows: 50px 1fr 50px;
}
section header {
grid-column: 2;
grid-row: 1;
}
section nav {
grid-column: 1;
grid-row: 2;
}
section article {
grid-column: 2;
grid-row: 2;
}
section aside {
grid-column: 3;
grid-row: 2;
}
section footer {
grid-column: 2;
grid-row: 3;
}In the simplest case, all that needs to be done is to indicate in the container (section) that the contents inside it should be arranged on a grid and set a virtual grid using the grid-columns and grid-rows properties (I’ll talk about what values they take). Further for each element inside it is enough to say where it should be located.

And it's all! Total:
- Virtual grid : grid-column s and grid-row s in container
- Element placement : grid-column and grid-row.
Now let's understand the details and additional features.
Virtual grid
Tracks: Rows and Columns
To create a virtual grid, along which elements will be further placed, it is necessary to describe the grid tracks (Grid Tracks) - rows and columns inside the grid:
#grid {
display: grid;
grid-columns: 150px 1fr; /* два столбца */
grid-rows: 50px 1fr 50px; /* три строки */
}Grid lines
Tracks are located between the grid lines (Grid Lines), which, in turn, are located on the right-left and top-bottom of each track:

To specify how the element will be placed on the grid, you need to indicate which line vertically and horizontally will be attached:
#item {
grid-column: 2;
grid-row: 2;
}
By default, an element takes up space from the specified line to the next (therefore, such numbering coincides with cell numbering and everything looks as if we are talking in which cell to place the element).
Stretch over multiple cells
To stretch an element over several grid cells, you can use the grid-row-span and grid-column-span properties :
#item {
grid-column: 2;
grid-column-span: 3;
grid-row: 2;
grid-row-span:2;
}
By default, both properties are set to 1, which corresponds to stretching the available space from the specified line to the next (+1).
Repeating tracks
It often happens that the grid intended for use contains some characteristic pattern:
#grid {
display: grid;
grid-columns: 24px 120px 24px 120px 24px 120px 24px 120px 24px;
grid-rows: 1fr 24px 1fr 24px 1fr 24px;
}
It would be convenient to describe such grids in a more compact and transparent form - and there is such an opportunity! The example above can be described as follows:
#grid {
display: grid;
grid-columns: 24px (120px 24px)[4];
grid-rows: (1fr 24px)[3];
}The pattern itself is described in parentheses, after which the number of repetitions is indicated in square brackets.
===
Now that we know the basic possibilities for describing grid lines, let's go back to the tracks and try to deal with the units used.
Units
As you can see above, in places I used an unusual value when specifying the sizes of some columns and rows - 1fr. We will talk about this and other possible values when specifying the length.
When describing the width of the columns and the height of the lines (track sizes), the following units and values can be used:
- linear dimensions are standard length units defined in the CSS3 Values and Units module , for example, pt, px, em, vw, etc.
- percent - the size of the track as a percentage of the size of the container with the grid (although if the height or length of the grid depends on the content, the result will be undefined);
- fractions - a non-negative number followed by the unit of measure fr , the size of each fraction is taken proportional to the specified number (see below for more details);
- max-content - a keyword to indicate the maximum length of the maximum lengths of elements in a track;
- min-content - a keyword to indicate the maximum length of the minimum lengths of elements in the track;
- minmax (min, max) - sets the range of values (the principle of operation can be described as minmax (p, q) = max (p, min (fill-available, q))
- the maximum of the lower threshold and the minimum of available space and the upper threshold); - auto is a keyword equivalent to minmax (min-content, max-content) .
Shares
Let's try to figure out how fraction values work. The grid takes up some space in width and height. It may depend on the content, be rigidly fixed, or occupy all available space in an external container. Further, when describing the tracks of a part of columns and lines, you can explicitly set what size they should be, for another part you can indicate that their length depends on the content.
Now, if you subtract the sum of all such explicit or “content” lengths from the available length allocated for the grid vertically or horizontally, the remaining space is distributed between the remaining tracks in proportion to the proportions indicated in them (the size of the fraction divided by the sum of all such shares):

In the example above, these are three columns with widths in the ratio 2: 1: 1 and two rows with heights in the ratio 5: 2.
Example
The draft specification provides such a comprehensive example that allows you to see this whole scheme with different types of values at once:
#grid {
display: grid;
grid-columns: 100px 1fr max-content minmax(min-content, 1fr)
}Here the following lines are defined (tracks, they are columns in this case):
- Starting first line.
- The line is 100px from the first.
- Another line at 1/2 of the remaining space after all calculations is from the second line.
- And one more line, whose distance from the third is the maximum of the sizes of the content of the elements in the column.
- Finally, the last line, located from the fourth at a distance equal to either the minimum length of the elements in the column, or 1/2 of the remaining space, whichever is greater.
There is still a small nuance regarding the accounting for shares that were inside the minmax function: they are taken into account in the total amount of shares only if indicated in the maximum position. Shares indicated in the minimum position are considered equal to 0px. For more details on the calculation, see the specification.
===
The next step is to try to figure out how the elements are placed between the grid lines (inside the cells).
Binding Elements
Now that the elements are “tied” to the grid lines, a natural question arises: how are they located between the lines?

The binding of elements to the cell borders is controlled using the grid-column-align and grid-row-align properties . The following values can be used for control:
- start
- end
- center
- stretch
I think the actions are obvious from the name, I only note that in each case we are talking about positioning an element according to its margin box. The default value is stretch.

The anchor in the columns (horizontally) corresponds to the direction of the text (for example, in Arabic, start will be on the right and end will be on the left). The snapping in rows (vertically) coincides with the direction of the flow of blocks (this, by the way, means that in some East Asian languages, rows and columns can swap places).
Layer management
The next important point: the arrangement of elements inside the grid with overlays. What happens if, for example, two elements are attached to the same lines, or are superimposed when expanding to several cells?
First of all, it is important to understand the following nuance: the elements placed inside the grid do not directly affect the location of each other. If you tie ten elements, say, to the second line horizontally and the third line vertically, then by default they will all be placed one on top of the other, as if each of them is tied to the corresponding corner. Elements can only affect the size of the tracks, if they are tied, in turn, to the size of the content.

To control the display order of such layers, the current version of the specification expands the capabilities of z-index, allowing you to control the layers of elements inside the grid.
Note : in the previous version of the specification, based on the current version of IE10 (platform preview 5), a separate grid-layer property was defined for these purposes , so as not to conflict with z-index, however, later in the discussion in the working group this solution was revised.
Usage example:
#grid {
display: grid;
grid-columns: (1fr)[3];
grid-rows: (1fr)[4];
}
#A {
grid-column:1;
grid-row:3;
grid-column-span:2;
}
#B {
grid-column:1;
grid-row:1;
grid-row-span:2;
/* grid-layer: 10; */
z-index:10;
margin-top:10px;
}
#C {
grid-column:1;
grid-row:1;
grid-column-span:2;
margin-left:50px;
}
#D {
grid-column:2;
grid-row:3;
grid-row-span:2;
grid-column-span:2;
margin:10px 0 0 10px;
}
#E {
grid-column:2;
grid-row:2;
/* grid-layer: 5; */
z-index:5;
margin: -20px;
}
css3 grid library
To start working with grids in browsers (not yet) supporting the CSS Grid Layout module, you can use the eCSStender js library and the CSS3 Grid Alignment extension , which support the following properties:
- display: grid
- grid-columns & grid-rows
- grid-column & grid row
- grid-column-span & grid-row-span
An example of work can be found here .
A little about the future, or what other features are described in the module
Finally, let's slightly open the door to the future and take a look at what other possibilities are being prepared in the CSS3 Grid Layout module .
Please note that for today the features mentioned below are only described in the draft specification, but do not yet have support among released browsers (including pre-release versions). They may also change in the future depending on the community reaction and recommendations of the CSS working group.
Specify the end line for snapping an item
Optionally, to snap an element to the grid, you can specify not only the start, but also the end line.
#item {
grid-column: 2;
grid-row: 2 4;
}
Unlike the span mechanism, which says how many cells an element should stretch horizontally or vertically, this feature allows you to clearly indicate on which line the element should end. It is also convenient to use in combination with the ability to name individual grid lines.
Named Grid Lines
For convenience, the lines can be given names. This is done by inserting string values in the corresponding places in the description of the tracks (you can give several names if this makes practical sense, for example, in terms of markup semantics):
#grid {
display: grid;
grid-columns: "nav" "first" 150px "content" 1fr "last";
grid-rows: "header" 50px "content" 1fr "footer" 50px;
}Further, when describing element binding, you can refer to these names:
#menu {
grid-column: "nav";
grid-row: "content";
}
#header {
grid-column: "content";
grid-row: "header";
}
#article {
grid-column: "content";
grid-row: "content";
}
The specification also introduces 4 pre-named lines - vertical and horizontal start and end , in fact, framing the entire grid. This allows, for example, to position the element "from the second column to the last", without thinking about the total number of columns.
#menu {
grid-column: 1;
grid-row: start end;
}
#footer {
grid-column: 2 end;
grid-row: 3;
}

Named Cells and Templates
Another way to place elements on a grid is to use templates to describe the virtual structure of blocks:
#grid {
display: grid;
grid-template: "ln"
"ma"
"ba"
"ff";
grid-columns: auto minmax(min-content, 1fr);
grid-rows: auto minmax(min-content, 1fr) auto auto;
}
At the same time, to place an element with a buckle to one or another virtual cell, it is enough to refer to it with the corresponding rule:
#article {
grid-cell: "a";
}This approach is especially convenient if, depending on various conditions, for example, screen resolution, you need to change the arrangement of elements and even redo the grid itself. In a similar situation, Grid Layout goes well with Media Queries:
@media (orientation: portrait) {
#grid {
display: grid;
grid-template: "ln"
"ma"
"ba"
"ff";
grid-columns: auto minmax(min-content, 1fr);
grid-rows: auto minmax(min-content, 1fr) auto auto;
}
}
@media (orientation: landscape) {
#grid {
display: grid;
grid-template: "ln"
"ma"
"mb"
"sf";
grid-columns: auto minmax(min-content, 1fr);
grid-rows: auto minmax(min-content, 1fr) auto auto;
}
}
#article {
grid-cell: "a";
}
Note that the binding of the article itself to the named cell does not change. (Pens are already itching to start using, however, we are waiting for it to be implemented in browsers.)
Conclusion
Я постарался дать в статье обзор ключевых возможностей модуля CSS3 Grid Layout. Надеюсь, они вдохновляют вас не менее, чем меня. :)
Напомню, что модуль продолжает развиваться, редакторы собирают отзывы от внешнего сообщества и внутри рабочей группы CSS. На действующую реализацию основного функционала можно посмотреть в Internet Explorer 10. Несколько интересных примеров можно найти на ietestdrive.com: The Grid System и Hands On: CSS3 Grid Layout:

Также еще раз отмечу, что возможности Grid Layout, уже поддерживаемые движком IE10, также можно использовать при разработке приложений в стиле Metro на HTML/JS для Windows 8.