CSS 网格布局中列的倒序

问题描述 投票:0回答:10

我希望使用 CSS Grid 来反转两个并排 div 的明显顺序,其中一个 div 任意增长(我不想使用浮动)。

我在这里创建了一个 plunkr: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
类(这样你应该看到
B | A
),
B
被偏移到一个新行所以它看起来更像:

          | A
B

如果我用

.a
反转
.b
的文档顺序,这会恢复正常(当然,如果我放弃
.reverse
类,我会遇到同样的问题)。

为什么会这样,我该如何解决?

html css css-grid
10个回答
72
投票

当网格自动放置算法在容器中布置项目时,它使用 next available empty cells (source).

在您的源代码中,A 元素位于 B 元素之前:

<div id="container" class="reverse" style="width: 800px;">
   <div class="a">A</div>
   <div class="b">B</div>
</div>

因此,网格容器先放置A,然后使用下一个可用空间放置B。

默认情况下,自动放置算法在网格中看起来是线性的,没有回溯;如果它必须跳过一些空白空间来放置更大的项目,它就不会返回来填充这些空间。要更改此行为,请在

dense
中指定
grid-auto-flow
关键字。

http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement


grid-auto-flow: dense

这个问题的一个解决方案(如您所见)是用

grid-auto-flow: row
覆盖默认
grid-auto-flow: dense

使用

grid-auto-flow: dense
,网格自动放置算法将使用适合的项目回填未占用的单元格。

#container {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-auto-flow: dense; /* NEW */
}

7.7。自动放置:

grid-auto-flow
属性

未明确放置的网格项目会自动放置到 自动放置在网格容器中的未占用空间 算法。

grid-auto-flow
控制自动放置算法的工作方式, 准确指定自动放置的项目如何流入网格。

dense

如果指定,自动放置算法使用“密集”包装 算法,如果 较小的项目稍后出现。这可能会导致项目出现 无序,这样做会填补较大物品留下的空洞。

#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>


55
投票

最简单的方法是在

order: 1
中将
order: -1
添加到元素B或
.reverse

到元素A

它也是正确的 CSS 而不是 hack-y


24
投票

我不确定如何反转更多网格项。但是如果你的网格中有 2 个网格项,你可以简单地使用下面的代码定位第二个网格项。

#container > .b {
    grid-column-start: 1;
    grid-row-start: 1;
}

12
投票

我刚才有同样的问题。我尝试了 auto-row-dense,然后将容器父级的方向设置为 rtl。它奏效了。

只是这个,在 plunker 链接上,似乎可以解决问题。

.reverse{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: dense;
  direction: rtl;
}

4
投票

您可以使用方向属性来反转网格 x 轴顺序。 嵌套元素也会反转,因此您必须确保添加额外的样式来修复此行为。

<div class="grid">
  <div class="grid-item"><div>
</div>

<style>
.grid { direction : rtl; }
.grid-item { direction : ltr; }
</style>

编辑:这可能有效,但可能会导致可访问性问题。


3
投票

方孔圆钉

请记住,即使您正在使用花哨的“新”网格功能,旧的 flex 布局仍然可以使用。你可以将它们组合起来,嵌套它们,有时你不得不承认像这样的某些问题可能会用旧的

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;
}

这是一个更复杂的示例,该示例将这种技术与媒体查询一起使用.


1
投票

我发现:我需要在容器上涂抹

grid-auto-flow: dense;

#container {
  grid-template-columns: 240px 1fr;
  display: grid;
  grid-auto-flow: dense;
}

根据 MDN,该算法尝试填充网格中较早的孔。


0
投票

我想提一个在某些情况下也与这个问题相关的解决方案。当有一个多行布局时,你想要

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>


0
投票

如果你正在使用像 SCSS 这样的东西,你可以使用:

#container {
  direction: rtl;
  & > * {
    direction: ltr;
  }
}

请注意,在 rtl 语言环境中,您可能需要添加:

[dir='rtl'] #container {
  direction: ltr;
  & > * {
    direction: rtl;
  }
}

-3
投票

我发现:我需要应用 grid-auto-flow: dense;在容器上:

© www.soinside.com 2019 - 2024. All rights reserved.