CSS 网格布局中列的逆序
Reverse order of columns in CSS Grid Layout
我希望使用 CSS 网格来反转两个并排 div 的明显顺序,其中一个 div 任意增长(我不想使用浮动)。
我在这里创建了一个插件:http://plnkr.co/edit/6WZBnHbwhD7Sjx2ovCO7?p=preview
#container {
grid-template-columns: 240px 1fr;
display: grid;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
问题的症结在于,当我应用 .reverse
class 时(这样您应该会看到 B | A
),B
偏移到新行所以它看起来更像:
| A
B
如果我用 .b
反转 .a
的文档顺序,这会恢复正常(当然,如果我删除 .reverse
class,我遇到同样的问题)。
为什么会这样,我该如何解决?
我发现:我需要在容器上应用grid-auto-flow: dense;
:
#container {
grid-template-columns: 240px 1fr;
display: grid;
grid-auto-flow: dense;
}
According to MDN,此算法试图填补网格中较早的空洞。
当网格自动放置算法在容器中布置项目时,它使用下一个可用个空单元格(source)。
在您的源代码中,A 元素位于 B 元素之前:
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
因此,网格容器首先放置A,然后使用下一个可用的space放置B。
By default, the auto-placement algorithm looks linearly through the grid without backtracking; if it has to skip some empty spaces to place a larger item, it will not return to fill those spaces. To change this behavior, specify the dense
keyword in grid-auto-flow
.
http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement
grid-auto-flow: dense
此问题 () 的一个解决方案是用 grid-auto-flow: dense
覆盖默认值 grid-auto-flow: row
。
使用 grid-auto-flow: dense
,网格自动放置算法将使用适合的项目回填未占用的单元格。
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
7.7. Automatic Placement: the grid-auto-flow
property
Grid items that aren’t explicitly placed are automatically placed into
an unoccupied space in the grid container by the auto-placement
algorithm.
grid-auto-flow
controls how the auto-placement algorithm works,
specifying exactly how auto-placed items get flowed into the grid.
dense
If specified, the auto-placement algorithm uses a “dense” packing
algorithm, which attempts to fill in holes earlier in the grid if
smaller items come up later. This may cause items to appear
out-of-order, when doing so would fill in holes left by larger items.
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
grid-row: 1
另一种解决方案是简单地为第二项定义行。
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container {
display: grid;
grid-template-columns: 240px 1fr;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
我不确定如何反转更多网格项。但是如果你的网格中有 2 个网格项目,你可以简单地使用下面的代码定位第二个网格项目。
#container > .b {
grid-column-start: 1;
grid-row-start: 1;
}
我发现:我需要应用 grid-auto-flow: dense;在容器上:
我刚才遇到了同样的问题。我尝试了 auto-row-dense,然后将容器父级的方向设置为 rtl。成功了。
就是这个,在 plunker link 上,似乎可以解决问题。
.reverse{
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
direction: rtl;
}
方孔圆钉
请记住,即使您正在使用花哨的 'new' 网格功能,旧的弹性布局仍然可以使用。你可以组合它们,嵌套它们,有时你不得不承认像这样的某些问题可能只是用旧的更好地解决
flex-direction: row-reverse
但我知道有些人会因此而对我投反对票,所以这是另一种使用网格的方式。
使用命名模板区域
您可以使用命名模板区域并在定义中反转它们。
#container
{
grid-template-areas: a b;
grid-template-rows: 240px 1fr;
display: grid;
}
#container.reverse
{
// note the order is flipped for both these properties
grid-template-areas: b a;
grid-template-rows: 1fr 240px;
}
.a {
grid-area: a;
background: yellow;
}
.b {
grid-area: b;
background: blue;
color: white;
}
Here's an more complex example that uses that technique with media queries
最简单的方法是在.reverse
中向元素B添加order: 1
或向元素A添加order: -1
这也是正确的 CSS 而不是 hack-y
您可以使用方向 属性 来反转网格 x-axis 顺序。
嵌套元素也会反转,因此您必须确保添加额外的样式来修复此行为。
<div class="grid">
<div class="grid-item"><div>
</div>
<style>
.grid { direction : rtl; }
.grid-item { direction : ltr; }
</style>
我想提一个在某些情况下也与这个问题相关的解决方案。当具有 multi-row 布局时,您想要 reversed
查看网格的填充方式。
您可以将 grid-start
与一些 :nth-child
和 :last-child
选择器结合使用以实现反向自动流。
反转grid-auto-flow: column
.container{
display: grid;
width: 10rem;
gap: 0.5rem;
grid-template-rows: repeat(2, 1fr);
grid-auto-flow: column; /* => vertical grid*/
}
/* REMOVE THIS TO SEE THE DIFFERENCE */
.pixel:nth-child(odd):last-child { /* reversed auto-flow: column */
grid-row-start: 2;
}
.pixel{
width: 2rem;
height: 2rem;
background: red;
border: 1px solid black
}
<div class="container">
<!-- ADD/REMOVE SOME PIXELS to see the result -->
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
</div>
颠倒:水平和垂直
.container{
display: grid;
width: 10rem;
gap: 0.5rem;
grid-template-rows: repeat(2, 1fr);
grid-auto-flow: column;
direction: rtl; /* reversed horizontal */
}
/* REMOVE THIS TO SEE THE DIFFERENCE */
.pixel:nth-child(odd):last-child { /* reversed vertical */
grid-row-start: 2;
}
.pixel{
width: 2rem;
height: 2rem;
background: red;
border: 1px solid black
}
<div class="container">
<!-- ADD/REMOVE SOME PIXELS to see the result -->
<div class="pixel">1</div>
<div class="pixel">2</div>
<div class="pixel">3</div>
<div class="pixel">4</div>
<div class="pixel">5</div>
<div class="pixel">6</div>
<div class="pixel">7</div>
</div>
我希望使用 CSS 网格来反转两个并排 div 的明显顺序,其中一个 div 任意增长(我不想使用浮动)。
我在这里创建了一个插件:http://plnkr.co/edit/6WZBnHbwhD7Sjx2ovCO7?p=preview
#container {
grid-template-columns: 240px 1fr;
display: grid;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
问题的症结在于,当我应用 .reverse
class 时(这样您应该会看到 B | A
),B
偏移到新行所以它看起来更像:
| A
B
如果我用 .b
反转 .a
的文档顺序,这会恢复正常(当然,如果我删除 .reverse
class,我遇到同样的问题)。
为什么会这样,我该如何解决?
我发现:我需要在容器上应用grid-auto-flow: dense;
:
#container {
grid-template-columns: 240px 1fr;
display: grid;
grid-auto-flow: dense;
}
According to MDN,此算法试图填补网格中较早的空洞。
当网格自动放置算法在容器中布置项目时,它使用下一个可用个空单元格(source)。
在您的源代码中,A 元素位于 B 元素之前:
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
因此,网格容器首先放置A,然后使用下一个可用的space放置B。
By default, the auto-placement algorithm looks linearly through the grid without backtracking; if it has to skip some empty spaces to place a larger item, it will not return to fill those spaces. To change this behavior, specify the
dense
keyword ingrid-auto-flow
.http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement
grid-auto-flow: dense
此问题 (grid-auto-flow: dense
覆盖默认值 grid-auto-flow: row
。
使用 grid-auto-flow: dense
,网格自动放置算法将使用适合的项目回填未占用的单元格。
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
7.7. Automatic Placement: the
grid-auto-flow
propertyGrid items that aren’t explicitly placed are automatically placed into an unoccupied space in the grid container by the auto-placement algorithm.
grid-auto-flow
controls how the auto-placement algorithm works, specifying exactly how auto-placed items get flowed into the grid.
dense
If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.
#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
grid-row: 1
另一种解决方案是简单地为第二项定义行。
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container {
display: grid;
grid-template-columns: 240px 1fr;
}
.a {
background: yellow;
}
.b {
background: blue;
color: white;
}
#container>.a {
grid-column: 1;
}
#container>.b {
grid-column: 2;
grid-row: 1; /* NEW */
}
#container.reverse>.a {
grid-column: 2;
}
#container.reverse>.b {
grid-row: 1;
grid-column: 1;
}
<div id="container" class="reverse" style="width: 800px;">
<div class="a">A</div>
<div class="b">B</div>
</div>
我不确定如何反转更多网格项。但是如果你的网格中有 2 个网格项目,你可以简单地使用下面的代码定位第二个网格项目。
#container > .b {
grid-column-start: 1;
grid-row-start: 1;
}
我发现:我需要应用 grid-auto-flow: dense;在容器上:
我刚才遇到了同样的问题。我尝试了 auto-row-dense,然后将容器父级的方向设置为 rtl。成功了。
就是这个,在 plunker link 上,似乎可以解决问题。
.reverse{
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
direction: rtl;
}
方孔圆钉
请记住,即使您正在使用花哨的 'new' 网格功能,旧的弹性布局仍然可以使用。你可以组合它们,嵌套它们,有时你不得不承认像这样的某些问题可能只是用旧的更好地解决
flex-direction: row-reverse
但我知道有些人会因此而对我投反对票,所以这是另一种使用网格的方式。
使用命名模板区域
您可以使用命名模板区域并在定义中反转它们。
#container
{
grid-template-areas: a b;
grid-template-rows: 240px 1fr;
display: grid;
}
#container.reverse
{
// note the order is flipped for both these properties
grid-template-areas: b a;
grid-template-rows: 1fr 240px;
}
.a {
grid-area: a;
background: yellow;
}
.b {
grid-area: b;
background: blue;
color: white;
}
Here's an more complex example that uses that technique with media queries
最简单的方法是在.reverse
order: 1
或向元素A添加order: -1
这也是正确的 CSS 而不是 hack-y
您可以使用方向 属性 来反转网格 x-axis 顺序。 嵌套元素也会反转,因此您必须确保添加额外的样式来修复此行为。
<div class="grid">
<div class="grid-item"><div>
</div>
<style>
.grid { direction : rtl; }
.grid-item { direction : ltr; }
</style>
我想提一个在某些情况下也与这个问题相关的解决方案。当具有 multi-row 布局时,您想要 reversed
查看网格的填充方式。
您可以将 grid-start
与一些 :nth-child
和 :last-child
选择器结合使用以实现反向自动流。
反转grid-auto-flow: column
.container{
display: grid;
width: 10rem;
gap: 0.5rem;
grid-template-rows: repeat(2, 1fr);
grid-auto-flow: column; /* => vertical grid*/
}
/* REMOVE THIS TO SEE THE DIFFERENCE */
.pixel:nth-child(odd):last-child { /* reversed auto-flow: column */
grid-row-start: 2;
}
.pixel{
width: 2rem;
height: 2rem;
background: red;
border: 1px solid black
}
<div class="container">
<!-- ADD/REMOVE SOME PIXELS to see the result -->
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
<div class="pixel"></div>
</div>
颠倒:水平和垂直
.container{
display: grid;
width: 10rem;
gap: 0.5rem;
grid-template-rows: repeat(2, 1fr);
grid-auto-flow: column;
direction: rtl; /* reversed horizontal */
}
/* REMOVE THIS TO SEE THE DIFFERENCE */
.pixel:nth-child(odd):last-child { /* reversed vertical */
grid-row-start: 2;
}
.pixel{
width: 2rem;
height: 2rem;
background: red;
border: 1px solid black
}
<div class="container">
<!-- ADD/REMOVE SOME PIXELS to see the result -->
<div class="pixel">1</div>
<div class="pixel">2</div>
<div class="pixel">3</div>
<div class="pixel">4</div>
<div class="pixel">5</div>
<div class="pixel">6</div>
<div class="pixel">7</div>
</div>