一尘不染

如何展平嵌套的div以在CSS网格中显示它们?

css

我从应该是两列宽的对象生成一个表(使用vue.js)。每个列都来自对象的键和值。这等效于以下实际HTML:

<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

我使用CSS网格将其格式化div为2x2网格,我希望这是

this is something long on the first row | short 1st row
wazaa 2nd row                           | wazii 2nd row

这样做的代码:

#table {

  display: grid;

  grid-template-columns: auto 1fr;

}


<div id="table">

  <div>

    <div>

      this is something long on the first row

    </div>

    <div>

      short 1st row

    </div>

  </div>

  <div>

    <div>

      wazaa 2nd row

    </div>

    <div>

      wazii 2nd row

    </div>

  </div>

</div>

结果不是我期望的结果:两个最深的区域的div行为就像它们应该在grid显示器之外:它们彼此堆叠。

我希望他们继承网格行为:在进行时根据列模板进行对齐。 如何实现?


阅读 242

收藏
2020-05-16

共1个答案

一尘不染

网格属性不适用于您的内容div,因为这些div不在范围内。

网格格式仅限于父子关系。这意味着网格容器始终是父级,而网格项目始终是子级。子代之外的网格容器的后代不属于网格布局,并且不接受网格属性。

由于您的内容div比网格容器(#table)低两级,使它们成为子代而不是子代,因此它们不是网格项目,并且不接受网格属性。


上面的规则有一些例外,但它们没有太多或任何浏览器支持。

display:contents涵盖了。它使元素可以被父元素忽略为包含块,因此父元素会将其子元素识别为普通子元素。但是目前,由于对浏览器的支持较弱,因此该方法实际上无法用于生产目的。

在这种情况下,更合适的解决方案是display: subgrid使网格容器的子代超出子代(即,网格项的子代)以遵守容器的行。但是此功能不支持浏览器。


如果您想要一个纯CSS解决方案,也许结合使用grid和flex会有所帮助。

这是一个基本概念。HTML不变。

#table {

  display: grid;

  grid-template-columns: 1fr;

}



#table > div {

  display: flex;

}



#table > div > div {

  flex: 1;

}


<div id="table">

  <div>

    <div>

      this is something long on the first row

    </div>

    <div>

      short 1st row

    </div>

  </div>

  <div>

    <div>

      wazaa 2nd row

    </div>

    <div>

      wazii 2nd row

    </div>

  </div>

</div>
2020-05-16