πŸ“œ ⬆️ ⬇️

A step-by-step guide to the CSS Grid auto-placement algorithm



We bring to your attention a translation of an article about a technique that will be useful to developers using CSS in their work.

In this guide, we will cover all the steps of the algorithm for automatically placing elements from the CSS Grid Layout module. Each stage is controlled by the grid-auto-flow property. In his other articles, β€œ Introducing the CSS Grid Layout ” and β€œ Seven Ways You Can Place Your Elements Using the CSS Grid Layout, ” the author reviewed the CSS Grid specification and analyzed how using the Grid to position elements on a web page. However, in these materials, the position of a single element was explicitly specified in the grid. The remaining elements were placed using a certain algorithm.
')
Now we will analyze this algorithm. And the next time you find that the item was not where you need it, you won’t have to scratch your head and wonder how it happened.

Basic principles


Before delving into the details, consider some basic principles.


Now you need to note this. The default value of the grid-auto-flow property, with which we manage the algorithm, is row . The same value will be used in the subsequent explanation of the algorithm. If you explicitly set the column value for the property, do not forget in this explanation to replace all instances of the row row with the column. For example, β€œ Placing elements using the row-position setting, not column ” will turn into β€œ Placing elements using the column-position setting, not row ”.

Now activate in your favorite modern browser the possibility of using experimental functions , and consider the details of the algorithm when building the layout.

Stage # 1: Generating Anonymous Grid Elements


The first thing the algorithm does when it tries to put all the elements in the grid is that it creates anonymous elements. As mentioned above, you cannot apply styles to such elements, because there is simply nothing to apply them to.

The following code generates an anonymous mesh element from inter-element text:

 <div class="container"> <span class="nonan">1</span> Anonymous Item <div class="nonan floating">2</div> <div class="nonan">3</div> <div class="nonan floating">4</div> <div class="nonan">5</div> </div> 

In this example, it should be noted that the algorithm ignores CSS floats applied to div 2 and div 4.

β†’ CodePen Demo

Stage # 2: Placing items in clearly indicated positions


For this and the next few steps, we will use a grid of nine different elements.

 <div class="container"> <div class="item a">A</div> <div class="item b">B</div> <div class="item c">C</div> <div class="item d">D</div> <div class="item e">E</div> <div class="item f">F</div> <div class="item f">G</div> <div class="item f">H</div> <div class="item f">I</div> </div> 

The first elements in the grid will be placed for which positions are explicitly indicated . In our case, let it be elements A and B. For now, ignore all the others. Set the positions for A and B:

 .a { grid-area: 1 / 2 / 2 / 3; } .b { grid-area: 2 / 1 / 4 / 3; } 


The algorithm places A and B according to their values ​​of the grid-area property:


β†’ CodePen Demo

Stage # 3: Placing elements using row-position settings, not column


Now the algorithm places an element with explicitly specified row-positions in the grid-row-start and grid-row-end properties.

Set the value of grid-row for C and D elements:

 .c { grid-row-start: 1; grid-row-end: 3; } .d { grid-row-start: 1; grid-row-end: 2; } 

To determine the column position, which is not explicitly specified, the algorithm operates in one of two scenarios in accordance with the packing mode :


Sparse placement on stage # 3


This is the default behavior. The initial row of the column (column-start line) of our item will receive the minimum possible line index (line index). This way we avoid overlapping space for the current element and cells already occupied by other elements.

The initial row of the column should also go after the element already placed in the same row at this stage . We emphasize: at this stage, and not up to this stage.


Consider an example: the element D did not move to the left of A, even though it could fit there without any overlaps. The fact is that the elements with an explicitly given row-position, and not column- , the algorithm does not place in front of another, similarly positioned element in this row (in our example - C). If element C is to remove grid-row values, then D moves to the left of A.

In other words, the element D, which is explicitly given a row-position, and not column, can be placed before A, but only if it does not interfere with C. And in this case it interferes, because C, like in D, a row position is defined, not a column, and it is in the same row as D.

β†’ CodePen Demo

Tight Stage # 3


If you need to fill D with an empty space before A, then you will have to assign row dense to the grid-auto-flow property.

 .container { grid-auto-flow: row dense; } 


In this case, the initial row of the column will again get the minimum possible index so that there are no overlaps with other elements. But if there is an empty space in the row where our element can fit without overlaps, then it will be placed there without taking into account the previous element from the same row and with the same positioning values ​​(in our example, C).

β†’ CodePen Demo

Step # 4: Determine the number of columns in the implicit grid


Next, the algorithm tries to determine the number of columns in the implicit grid. It happens like this:


Stage # 5: Placing Remaining Items


By this time, the algorithm has already placed all the elements whose positions are clearly defined, as well as elements with known row positions. Now it starts placing the remaining elements in the grid.

But before considering this process, we introduce a new term: the auto-placement cursor . This is the current insertion point in the grid, determined by the intersection of a pair of coordinates - a row and a column. Initially, the cursor is placed at the intersection point of the initial row and column of the implicit grid.

Recall that the positioning of the elements depends on the mode of placement (packing mode), specified by the property grid-auto-flow .

Sparse placement on stage # 5


By default, the remaining items are placed in a sparse mode . This is how it happens.

If the element does not have a position on any axis:


If element is set to column position:


To make it clearer, consider an example.


Placing elements E and F when no positions are specified on any axis


When processing the element E, for which neither column- nor row-position is specified, the values ​​of row 1 and column 1 are set for the cursor. Element E occupies only one cell, it can fit in the upper left corner without overlays. That is, the algorithm simply places the element E at the position of row 1 / column 1 .

The next element without specified positions on both axes is F. The value of the column position of the cursor increases to 2. But the position of row 1 / column 2 is already occupied by element A. The algorithm has to increase the value of the column position again until it reaches 4. There are no more columns , and then the row position of the cursor is increased by 1, and the column position is reset to 1: row 2 / column 1. The algorithm starts increasing the column position again by 1 until it reaches 4. Place with coordinates row 2 / column 4 while which is free and can be occupied by the element F. The algorithm places it and proceeds to the next element.

Placing the elements G and H when the column position is set


Let's start with G. The column position of the cursor is determined by the same as the grid-column-start property of element G - 3. Since they are smaller than the previous value of column (4), the row-position increases by 1. That is, it becomes row 3 / column 3. The space with such coordinates is currently free, and G can be placed there without overlaps, which the algorithm does. Then everything is the same for element H.

β†’ CodePen Demo

Tight placement on stage # 5


When the row dense assigned to the grid-auto-flow property, a different procedure is performed. If the inserted element does not have a specific position, then the current position of the cursor is determined in accordance with the line at the intersection of the initial row and column of the implicit grid, before the position of the element is determined.


Element I is placed to the left of H, because the cursor position is reset to the line located at the intersection of the initial row and column of the implicit grid , instead of starting from the last placed element. The algorithm searches for a suitable position without overlaps, finds a place to the left of H and places an element there.

β†’ CodePen Demo

Conclusion


In this article, we walked through all the stages of the automatic placement algorithm from the CSS Grid Layout module. This algorithm is controlled by the grid-auto-flow property.

Try yourself to calculate the last position of different elements from different layouts in order to better understand the operation of the algorithm.

Source: https://habr.com/ru/post/326098/


All Articles