【问题标题】:Reverse order of columns in CSS Grid LayoutCSS 网格布局中的列颠倒顺序
【发布时间】:2018-01-05 02:05:22
【问题描述】:

我希望使用 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

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

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

【问题讨论】:

    标签: html css css-grid


    【解决方案1】:

    最简单的方法是将order: 1添加到元素B或order: -1添加到.reverse中的元素A

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

    【讨论】:

      【解决方案2】:

      方孔圆钉

      请记住,即使您使用花哨的“新”网格功能,旧的 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;
      }
      

      Here's an more complex example that uses that technique with media queries

      【讨论】:

      • 投票支持“方孔中的圆钉” - 与 EWS 平行的英文是什么? (鸡蛋给羊毛奶猪?)
      【解决方案3】:

      我刚才也遇到了同样的问题。我尝试了自动行密集,然后将容器父级的方向设置为 rtl。它奏效了。

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

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

      【讨论】:

      • rtl 也会翻转文本和文本对齐,所以它不是一个非常好的内容解决方案。
      【解决方案4】:

      您可以将网格容器的方向设置为 rtl 但这将对齐其中的所有内容(如@Sascha 所述)

      direction: rtl; 
      

      【讨论】:

      • 这是一个相当糟糕的主意,因为它将一切从右到左对齐。例如,当您有选择字段时,它们的所有箭头按钮都会出现在右侧,这不是 OP 想要的。
      【解决方案5】:

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

      【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        当网格自动放置算法在容器中布置项目时,它使用下一个可用个空单元格 (source)。

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

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

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

        默认情况下,自动放置算法通过网格线性查找,无需回溯;如果它必须跳过一些空白空间来放置更大的项目,它不会返回来填充这些空间。要更改此行为,请在 grid-auto-flow 中指定 dense 关键字。

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


        grid-auto-flow: dense

        解决此问题 (as you have noted) 的一种方法是用 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-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>

        【讨论】:

        • 只是想注意dense 填充从网格开始到结束的空白空间。因此,如果您在放置的网格项目之前有两个空格,您将从左到右填充这些空格。
        【解决方案8】:

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

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

        According to MDN,此算法尝试在网格中较早地填充孔。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-10
          • 1970-01-01
          • 1970-01-01
          • 2015-06-21
          • 2018-06-22
          • 2018-04-15
          • 2011-04-19
          相关资源
          最近更新 更多