css网格
In this tutorial, I’ll be going over all the steps the auto-placement algorithm of the CSS Grid Layout module follows when positioning elements. These steps are controlled by the grid-auto-flow property.
在本教程中,我将介绍定位元素时CSS Grid Layout模块的自动放置算法所遵循的所有步骤。 这些步骤由grid-auto-flow属性控制。
In Introducing the CSS Grid Layout and Seven Ways You Can Place Elements Using CSS Grid Layout, I gave an overview of the CSS Grid spec and explained all the different ways Grid lets you arrange elements on the web. However, in my previous articles I explicitly specified the position of just one element in the grid. As for the rest of the items, they got placed properly based on an algorithm.
在介绍CSS网格布局和使用CSS网格布局放置元素的七种方法中 ,我概述了CSS Grid规范,并解释了Grid允许您在Web上排列元素的所有不同方式。 但是,在我以前的文章中,我明确指定了网格中一个元素的位置。 至于其余的物品,它们是根据算法正确放置的。
Here, I am going to show you how this algorithm works. This way, the next time an element ends up in an unexpected location, you are not left scratching your head wondering what just happened.
在这里,我将向您展示该算法的工作原理。 这样,下一次元素在意外位置结束时,您将不会想知道到底发生了什么而挠头。
Let’s go over some fundamental concepts before diving into the workings of the algorithm.
在深入研究算法工作之前,让我们仔细研究一些基本概念。
Anonymous grid items – If you place some text directly inside a grid container without wrapping it in any tag, it will form its own anonymous grid item. You can’t style an anonymous grid item because there is no element for you to style, but it still inherits style rules from its parent container. On the other hand, note that white space inside the grid container will not create its own anonymous grid item
匿名网格项目 –如果将一些文本直接放置在网格容器中而不将其包装在任何标签中,它将形成自己的匿名网格项目。 您无法设置匿名网格项目的样式,因为没有要设置样式的元素,但是它仍从其父容器继承样式规则。 另一方面,请注意,网格容器内的空白不会创建自己的匿名网格项
Value of grid spans – Unlike grid positions, the algorithm has no special rules to resolve the value of grid spans. If not explicitly specified, their value is set to 1 (the item only occupies its own cell)
网格跨度的值 –与网格位置不同,该算法没有解决网格跨度值的特殊规则。 如果未明确指定,则将其值设置为1(该项仅占用其自己的单元格)
Implicit grid – The grid built on the basis of the value of properties like grid-template-rows, grid-template-columns and grid-template-areas is called explicit grid. Now, if you specify the position of a grid item in such a way that it lies outside the bounds of the explicit grid, the browser will generate additional grid lines to accommodate the item. These lines, along with the explicit grid, form the implicit grid. You can read more about it in Where Things Are at in the CSS Grid Layout Working Draft. The auto-placement algorithm can also result in the creation of additional rows or columns in the implicit grid.
隐式网格 –基于诸如grid-template-rows , grid-template-columns和grid-template-areas类的属性值构建的网格称为显式网格 。 现在,如果您以某种方式指定网格项目的位置使其位于显式网格的边界之外,则浏览器将生成其他网格线来容纳该项目。 这些线与显式网格一起形成隐式网格。 您可以在CSS Grid Layout Working Draft中的“物在何处”中阅读有关它的更多信息。 自动放置算法还可导致在隐式网格中创建其他行或列。
Finally, I’d like to make the following preliminary point. The default value of the grid-auto-flow property, which is the property controlling the algorithm, is row. This is also the value I am going to assume in the following explanation of the auto-placement algorithm. On the other hand, if you explicitly set the above property to column, remember to replace instances of the term row with the term column in my explanation of the algorithm. For example, the step “Placement of Elements With a Set Row Position but No Set Column Position” will become “Placement of Elements With a Set Column Position but No Set Row Position”.
最后,我想提出以下初步要点。 grid-auto-flow属性的默认值是row ,它是控制算法的属性。 这也是我在自动放置算法的以下说明中要假定的值。 另一方面,如果您将上述属性显式设置为column ,请记住,在我对算法的解释中,请用术语列替换术语行的实例。 例如,“具有设置的行位置但没有设置的列位置的元素的放置”步骤将变为“具有设置的列位置但没有设置的行位置的元素的放置”。
Now, enable the experimental features flag in your favorite modern browser to follow along and let’s go over the details of all the steps the algorithm follows to build the layout.
现在,启用您喜欢的现代浏览器中的实验性功能标记 ,然后继续进行操作,让我们详细了解算法构建布局所遵循的所有步骤。
The first thing that happens when the algorithm is trying to place all the items inside a grid is the creation of anonymous grid items. As I mentioned earlier, you cannot style these elements because there is no item to apply the style to.
当算法尝试将所有项目放置在网格中时,发生的第一件事是创建匿名网格项目。 如前所述,您无法为这些元素设置样式,因为没有项目可将样式应用于该元素。
The markup below generates an anonymous grid item from the 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>Besides the generation of an anonymous item, one more thing to notice in the demo below is that the grid placement algorithm ignores the CSS floats applied to div 2 and div 4 .
除了生成一个匿名项目外,下面的演示中还有一点要注意的是,网格放置算法会忽略应用于div 2和div 4CSS浮点数。
See the Pen Anonymous Grid Items by SitePoint (@SitePoint) on CodePen.
请参阅CodePen上的SitePoint ( @SitePoint )的笔匿名网格项目 。
For this and the next few steps, I will be using a grid of nine different items to show how they are going to be placed.
对于此步骤和接下来的几个步骤,我将使用由9个不同项目组成的网格来显示如何放置它们。
Here’s the relevant markup:
这是相关的标记:
<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 items to be placed in the grid are those with an explicitly set position, which in the example below are items A and B. Just ignore all other items in the grid for now. Here is the CSS that explicitly sets the position of A and B:
放置在网格中的第一个项目是那些位置明确设置的项目,在下面的示例中是项目A和B。现在就忽略网格中的所有其他项目。 这是显式设置A和B位置CSS:
.a { grid-area: 1 / 2 / 2 / 3; } .b { grid-area: 2 / 1 / 4 / 3; }The algorithm positions items A and B according to the values of their respective grid-area property. In particular, the algorithm:
该算法根据项目A和B各自的grid-area属性的值来对其进行定位。 该算法特别是:
Sets the position of the top left corner of both A and B using the first and second value of the grid-area property
使用grid-area属性的第一个和第二个值设置A和B的左上角的位置
Sets the position of the bottom right corner of both A and B using the third and fourth value of thegrid-area property.
使用grid-area属性的第三个和第四个值设置A和B的右下角的位置。
The demo below illustrates the final placement of A and B after this step:
下面的演示说明了此步骤之后A和B的最终放置:
See the Pen Placing Elements with Explicit Positions by SitePoint (@SitePoint) on CodePen.
见笔配售与显性元素的位置由SitePoint( @SitePoint上) CodePen 。
Next, the algorithm places the elements whose row position has been set explicitly by using the grid-row-start and grid-row-end properties.
接下来,该算法使用grid-row-start和grid-row-end属性放置其行位置已明确设置的元素。
For this example, I will be setting only the grid-row values of item C and item D to give them a definite row position. Here is the CSS for placing both of them:
对于此示例,我将仅设置项C和项D的网格行值,以为其指定的行位置。 这是放置两者CSS:
.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 set, the algorithm behaves in one of two ways, according to the packing mode:
为了确定未明确设置的列位置,该算法根据填充模式以以下两种方式之一运行 :
sparse packing (default) 稀疏包装(默认) dense packing 密集包装This is the default behavior. The column-start line of our item will be set to the smallest possible line index which ensures that there won’t be any overlap between the item’s own grid area and the cells already occupied by other items. The column-start line also needs to be past any other item already placed in this row by this step. Please note that I wrote by this step and not until this step.
这是默认行为。 我们将项目的列起始行设置为最小的行索引,以确保该项目自己的网格区域与其他项目已经占据的单元格之间不会有任何重叠。 在此步骤中 ,列起始行还需要超过此行中已经放置的任何其他项目。 请注意,我是在这一步之前写的, 直到这一步为止 。
To clarify this point further, item D in the demo below did not move to the left of item A, even though it could fit in there without any overlap. This is due to the fact that the algorithm does not allow any item with an explicitly set row position but not set column position to be placed before any other similarly positioned item in that specific row (item C in this case). In fact, if you remove the grid-row rules applied to item C, then item D will move to the left of item A.
为了进一步说明这一点,以下演示中的项目D并未移至项目A的左侧,即使它可以毫无重叠地插入其中。 这是由于以下事实:该算法不允许将具有明确设置的行位置但没有设置列位置的 任何项目放置在该特定行中的任何其他类似放置的项目之前 (在这种情况下为项目C)。 实际上,如果删除应用于项目C的网格行规则,则项目D将移至项目A的左侧。
In short, item D, which has a definite row position but no explicitly set column position, can end up being placed before item A, but only if C does not interfere (interference takes place in this case because C, like D, has a definite row position but no set column position and is in the same row as D).
简而言之,具有确定的行位置但没有显式设置列位置的项D可以最终放置在项A之前,但前提是C不干扰(在这种情况下会发生干扰,因为C与D一样具有一个确定行位置,但没有设置列位置,并且与D在同一行)。
See the Pen Placing Elements with Definite Grid Positions by SitePoint (@SitePoint) on CodePen.
见笔放置有明确网格位置元素由SitePoint( @SitePoint上) CodePen 。
If you want to fill that empty space before item A with item D, you will have to set the value of the grid-auto-flow property to row dense.
如果要用项目D填充项目A之前的空白空间,则必须将grid-auto-flow属性的值设置为row dense 。
.container { grid-auto-flow: row dense; }In this case too, the column-start line is placed at the smallest index which does not cause any overlap with other grid items. The only difference is that this time, if there is some empty space in a row where our element can fit without any overlap, it will be placed in that position, without considering the previous item in the same row with the same position rules (in this case item C).
在这种情况下,也将列起始行放置在最小索引处,该索引不会引起与其他网格项目的任何重叠。 唯一的区别是这一次,如果一行中有一些空白空间可以容纳我们的元素而没有任何重叠,那么它将被放置在该位置,而无需考虑同一行中具有相同位置规则的前一项(在这个案例C)。
See the Pen Elements with Definite Grid Positions – Dense by SitePoint (@SitePoint) on CodePen.
请参见具有确定网格位置的钢笔元素-在CodePen上由SitePoint( @SitePoint ) 密集 。
Next, the algorithm tries to determine the number of columns in the implicit grid. This is done by following a series of steps:
接下来,该算法尝试确定隐式网格中的列数。 这是通过执行以下一系列步骤来完成的:
The algorithm starts with the number of columns in the explicit grid. 该算法从显式网格中的列数开始。 Then it goes through all the grid items with a definite column position and adds columns to the beginning and end of the implicit grid to accommodate all these items. 然后,它将遍历所有具有确定列位置的网格项目,并将列添加到隐式网格的开始和结尾以容纳所有这些项目。 Finally, it goes through all the grid items without a definite column position. If the biggest column span among these items is greater than the width of the implicit grid, it adds columns at the end of the grid to accommodate that column span. 最后,它遍历所有网格项而没有确定的列位置。 如果这些项目中最大的列跨度大于隐式网格的宽度,则会在网格末尾添加列以容纳该列跨度。At this point, the algorithm has placed all the items whose position has been explicitly specified as well as items whose row positions are known. Now, it will position all other remaining items in the grid.
此时,该算法已放置所有位置已明确指定的项目以及已知行位置的项目。 现在,它将在网格中放置所有其他剩余项目。
Before we go into more detail, you should know about the term auto-placement cursor. It defines the current insertion point in the grid, specified as a pair of row and column grid lines. To start off, the auto-placement cursor is placed at the start-most row and column in the implicit grid.
在更详细介绍之前,您应该了解术语“ 自动放置光标” 。 它定义了网格中的当前插入点,指定为一对行和列网格线。 首先,将自动放置光标放置在隐式网格中最开始的行和列。
Once more, the packing mode, determined by the value of the grid-auto-flow property, controls how these items are positioned.
再次,由grid-auto-flow属性的值确定的打包模式控制如何放置这些项目。
By default, the remaining items are placed sparsely. Here is the process the algorithm follows to place them.
默认情况下,其余项目将稀疏放置。 这是算法放置它们的过程。
If the item has no definite position in either axis:
如果项目在任一轴上都没有确定位置:
The algorithm increments the cursor’s column position until:
该算法递增游标的列位置,直到:
a) either there is no overlap between already placed items and the current item
a)已经放置的物品和当前物品之间没有重叠
b) or the cursor’s column position plus the item’s column span overflow the number of columns in the implicit grid.
b)或光标的列位置加上项目的列跨度溢出了隐式网格中的列数。
If such a non-overlapping position is found, the algorithm sets the item’s row-start and column-start values to the cursor’s current position. Otherwise, it increases the row-position by 1, sets column-start to the start-most line in the implicit grid and repeats the previous step.
如果找到了这样一个不重叠的位置,则该算法会将该项的row-start起始值和column-start起始值设置为光标的当前位置。 否则,它将行位置增加1,将column-start设置为隐式网格中的最开始的行,并重复上一步。
If the item has a definite column position:
如果项目具有确定的列位置:
The column position of the auto placement cursor is set to the item’s column-start line. If the value of this new position is less than the cursor’s previous column position, the row position is increased by one.
自动放置光标的列位置设置为项目的column-start行。 如果此新位置的值小于光标的上一列位置,则行位置将增加一。
Next, the row position is increased by one until the algorithm reaches a value where the grid item does not overlap with any of the occupied grid cells. If needed, extra rows can be added to the implicit grid. Now the item’s row start line is set to the cursor’s row position and the item’s row end line is set according to its span. 接下来,将行位置增加一个,直到算法达到一个网格项目不与任何占用的网格单元重叠的值。 如果需要,可以将额外的行添加到隐式网格。 现在,将项目的行起始行设置为光标的行位置,并根据其跨度来设置项目的行终止行。Let’s clarify the steps listed above with what’s happening in the following demo.
让我们用上面的演示来阐明上面列出的步骤。
When the algorithm deals with item E, which has no explicitly set column or row position, the auto-placement cursor is set to row 1 and column 1. Item E occupies just one cell and it can fit in the top left corner without any overlap. Therefore, the algorithm simply places item E at position row 1 / column 1.
当算法处理没有显式设置列或行位置的项目E时 ,自动放置光标将设置为第1行和第1列。项目E仅占据一个单元格,并且可以放在左上角而没有任何重叠。 因此,该算法仅将项E放置在位置行1 /列1处 。
The next item without an explicitly set column or row position is F. At this point, the column position for the auto-placement cursor is increased to 2. However, the position row 1 / column 2 is already occupied by item A. This means that the algorithm will have to keep increasing the column position. This goes on until the auto-placement cursor reaches column 4. Since there are no more columns, the row position for the auto-placement cursor is increased by 1 and the column position is set to 1. Now the row position is 2 and the column position is 1. The algorithm again starts increasing the column position by 1 until it reaches column 4. The space at row 2 and column 4 is currently empty and can be occupied by item F. The algorithm places item F there and moves on to the next item.
没有明确设置列或行位置的下一项是F。 此时,自动放置光标的列位置增加到2。但是,位置行1 /列2已被项A占用。这意味着算法将不得不继续增加列位置。 一直进行到自动放置光标到达第4列为止。由于没有更多列,因此自动放置光标的行位置增加了1,列位置设置为1。现在行位置是2,列位置是1。算法再次开始将列位置增加1,直到到达列4。 行2和列4的空间当前为空,并且可以由项F占用 。 该算法将项目F放置在此处,然后移至下一个项目。
The remaining items with a definite column position in our demo are G and H. Let’s examine G. The column position of the auto-placement cursor is set to be equal to the value of the grid-column-start property for item G, which is 3. Since this new value is less than the previous column value (which was 4), the row position is increased by one. The current row and column positions are now 3 and 3 respectively. The space at row 3 and column 3 is currently empty and item G can be placed there without any overlap. Therefore, the algorithm places item G there. The same steps are then repeated for the placement of item H.
在我们的演示中,具有确定的列位置的其余项是G和H。让我们检查G。 自动放置光标的列位置设置为等于项目G的grid-column-start属性的值,即3。由于此新值小于上一列的值(为4),行位置增加一。 现在,当前行和列位置分别为3和3。 当前第3行和第3列的空间为空,可以将项目G放置在此处而没有任何重叠。 因此,该算法将项目G放置在此处。 然后重复相同的步骤放置物品H。
See the Pen Positioning Remaining Items by SitePoint (@SitePoint) on CodePen.
见笔定位其余项目由SitePoint( @SitePoint )上CodePen 。
Things are handled a bit differently when the grid-auto-flow property is set to row dense. When placing a grid item with no definite position, the cursor’s current position is set to the start-most row and column line in the implicit grid before the item’s position is determined.
当grid-auto-flow属性设置为row dense时,事情的处理方式有所不同。 当将网格置于项目没有明确的位置,项目的位置,并判定光标的当前位置被设置为在隐格启动最行和列线。
Unlike the previous example, item I is placed to the left of item H because the cursor position gets reset to the start-most row and column line in the implicit grid instead of starting from the last item placed. At this point, while looking for a suitable position to place item I without any overlap, the cursor finds the spot to the left of item H and places it there.
与前面的示例不同,项目I放置在项目H的左侧,因为光标位置被重置为隐式网格中的最开始的行和列行 , 而不是从放置的最后一项开始 。 此时,在寻找合适的位置放置项目I且没有任何重叠时,光标会找到项目H左侧的位置并将其放置在该位置。
See the Pen Positioning Remaining Items – Dense by SitePoint (@SitePoint) on CodePen.
请参阅CodePen上剩余的笔定位项-按SitePoint( @SitePoint )的密集 程度 。
In this article, I went over all the steps followed by the auto-placement algorithm of the CSS Grid Layout module, controlled by the grid-auto-flow property.
在本文中,我介绍了由grid-auto-flow属性控制CSS Grid Layout模块的自动放置算法所遵循的所有步骤。
Have a go at figuring out the final position of different items in a few other layouts of your own to get a better understanding of the algorithm.
尝试找出您自己的其他几种布局中不同项目的最终位置,以更好地了解算法。
If you have any questions related to this article, let me know in the comments.
如果您对本文有任何疑问,请在评论中告诉我。
翻译自: https://www.sitepoint.com/a-step-by-step-guide-to-the-auto-placement-algorithm-in-css-grid/
css网格
相关资源:jdk-8u281-windows-x64.exe