【问题标题】:How can I make a div span multiple rows and columns in a grid?如何使 div 跨越网格中的多行和多列?
【发布时间】:2017-08-24 18:10:10
【问题描述】:

a previous question 为基础,我正在尝试将更大的块添加到我的网格布局中。在最后一个问题中,我需要一个 div 跨越多行。现在的问题是我需要一个 div 来跨越多行和列

如果我有一个五个元素的行,我怎么能把更大的元素放在它的中间? (正如float 自然而然地放在一边)。

这是一个示例 sn-p:

#wrapper{
  width: 516px;
}
.block{
  display: inline-block;
  width: 90px;
  height: 50px;
  margin: 5px;
  background-color: red;
}
.bigger{
  height: 110px;
}
.larger{
  height: 110px;
  width: 190px;
}
<div id="wrapper">
  <div class="block"></div>
  <div class="block bigger"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block larger"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
</div>

我不想将 display: grid 用于包装元素,因为 我可以使用 states 这是目前非常先进的技术。我希望有一个非网格非表格解决方案。

这是我想从上面sn-p 中得到的东西

【问题讨论】:

  • 可以修改 HTML 吗?
  • 如果您的 HTML 无法更改,我建议使用 Isotope 之类的库 - 不确定是否有纯 CSS 解决方案可以真正实现您的目标。
  • @Michael_B 我正在开发一个“2 块包装器”,但希望以另一种方式来实现它

标签: css flexbox grid-layout css-grid


【解决方案1】:

我了解到您正在寻求不涉及 HTML 表格CSS 网格布局 的答案。您提到由于浏览器支持较弱,您不想要 Grid。

但是,大约在您发布问题的同时,大多数主要浏览器都发布了新版本,提供对网格布局的全面支持(请参阅下面的详细信息)。


CSS Grid 让您的布局变得简单。无需更改 HTML、添加嵌套容器或在容器上设置固定高度 (see my flexbox answer on this page)。

#wrapper {
  display: grid;                            /* 1 */
  grid-template-columns: repeat(5, 90px);   /* 2 */
  grid-auto-rows: 50px;                     /* 3 */
  grid-gap: 10px;                           /* 4 */
  width: 516px;
}

.tall {
  grid-row: 1 / 3;                          /* 5 */
  grid-column: 2 / 3;                       /* 5 */
}

.wide {
  grid-row: 2 / 4;                          /* 6 */
  grid-column: 3 / 5;                       /* 6 */
}

.block {
  background-color: red;
}
<div id="wrapper">
  <div class="block"></div>
  <div class="block tall"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block wide"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
</div>

jsFiddle

它是如何工作的:

  1. Establish a block-level grid container.
  2. grid-template-columns 属性设置明确定义的列的宽度。在这种情况下,网格被指示创​​建一个 90px 宽度的列,并重复该过程 5 次。
  3. grid-auto-rows 属性设置自动生成的(隐式)行的高度。此处每行高 50 像素。
  4. grid-gap 属性是grid-column-gapgrid-row-gap 的简写。此规则在网格项目之间设置 10px 的间隙。 (不适用于物品和容器之间的区域。)
  5. Instruct the .tall item to span from row lines 1 to 3 and column lines 2 to 3.*
  6. Instruct the .wide item to span from row lines 2 to 4 and column lines 3 to 5.*

* 在五列网格中有六列线。在三行网格中有四行。


浏览器支持 CSS 网格

  • Chrome - 自 2017 年 3 月 8 日起提供全面支持(版本 57)
  • Firefox - 自 2017 年 3 月 6 日起提供全面支持(版本 52)
  • Safari - 自 2017 年 3 月 26 日起全面支持(版本 10.1)
  • Edge - 自 2017 年 10 月 16 日起提供全面支持(版本 16)
  • IE11 - 不支持当前规范;支持过时版本

这是完整的图片:http://caniuse.com/#search=grid

【讨论】:

  • 这太棒了!你知道我怎样才能让一个任意的盒子在不知道它的同伴的情况下增长吗?
  • @SB2055,你能提供更多细节吗?也许是一个可以工作的演示?或者考虑发布一个完整的新问题。
【解决方案2】:

保持你的 HTML 原样,布局在 flexbox 中是不可能的。这主要是因为 2 x 2 框占据了第三列和第四列。你能得到的最接近的是:

#wrapper{
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 180px;
  width: 516px;
}
.block {
  width: 90px;
  flex: 0 0 50px;
  margin: 5px;
  background-color: red;
}
.bigger{
  flex-basis: 110px;
}
<div id="wrapper">
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block bigger"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block bigger"></div>
  <div class="block"></div>
  <div class="block bigger"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
</div>

如您所见,大框在列之间被拆分。

正如other post you referenced 中提到的,由于您的子元素(.block)具有固定的高度,我们可以确定容器的高度(.wrapper)。

通过知道容器的高度,可以使用flex-direction: columnflex-wrap: wrap实现上面的布局。

容器上的固定高度用作断点,告诉弹性项目在哪里换行。

或者,如果您可以添加容器,那么布局很容易。只需创建四个嵌套的 flex 容器来容纳第 1、2、3-4 和 5 列,就完成了。

#wrapper {
  display: flex;
  width: 516px;
}

section {
  display: flex;
  flex-direction: column;
}

.block {
  width: 90px;
  height: 50px;
  margin: 5px;
  background-color: red;
}

.bigger {
  flex-basis: 110px;
}

section:nth-child(3) {
  flex-direction: row;
  flex-wrap: wrap;
  flex: 0 0 200px;
}

section:nth-child(3)>.block:last-child {
  flex: 0 0 190px;
  height: 110px;
}
<div id="wrapper">
  <section>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
  </section>
  <section>
    <div class="block bigger"></div>
    <div class="block"></div>
  </section>
  <section>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
  </section>
  <section>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
  </section>
</div>

否则,请参阅此帖子了解更多详细信息和其他选项:

【讨论】:

    【解决方案3】:

    使用 flexbox 和 flex-direction: row 来实现。

    #wrapper{
      width: 516px;
      display: flex;         /* added */
      flex-flow: row wrap;   /* added */
    }
    .block{
      display: inline-block;
      width: 90px;
      height: 50px;
      margin: 5px;
      background-color: red;
    }
    .block:last-child {
      margin-left: 205px;    /* added */
    }
    .bigger{
      height: 110px;
      margin-bottom: -55px;  /* added */
    }
    .larger{
      height: 110px;
      width: 190px;
      margin-left: 105px;    /* added */
      margin-bottom: -55px;  /* added */
    }
    <div id="wrapper">
      <div class="block"></div>
      <div class="block bigger"></div>
      <div class="block"></div>
      <div class="block"></div>
      <div class="block"></div>
      <div class="block"></div>
      <div class="block larger"></div>
      <div class="block"></div>
      <div class="block"></div>
      <div class="block"></div>
      <div class="block"></div>
    </div>

    【讨论】:

      猜你喜欢
      • 2017-08-14
      • 2012-12-15
      相关资源
      最近更新 更多