Flexbox包装没有媒体查询的嵌套行

时间:2017-08-16 11:30:18

标签: html css flexbox

我在flexbox网格中有四个div。我希望他们一次包装两个,如下:

+-----------------------+
|  1  |  2  |  3  |  4  | 
+-----------------------+
+-----------+
|  1  |  2  |
+-----------+    THIS IS WHAT I WANT
|  3  |  4  |
+-----------+
+-----+
|  1  |
+-----+
|  2  |
+-----+
|  3  |
+-----+
|  4  |
+-----+

现在,这看起来很容易,只需将它们嵌套在新的flex容器中并应用flex-wrap,并为细胞提供一些最小宽度。但是,这会产生使中间视图看起来像这样的副作用:

+-----------+
|  1  |  3  |
+-----------+    NOT WHAT I WANT
|  2  |  4  |
+-----------+

显然,flexbox首先要包装内部div而不是考虑它们的行。为了保持所有其他包装工作,为嵌套div设置flex-basis(例如100%)不是一个选项。为了保持一切动态(例如将第三个单元格添加到其中一个行),在单元格上设置%-widths不是一个选项。为了避免硬断点和基本包装(动态)内容宽度,我真的喜欢避免媒体查询。

这可以通过flexbox和没有媒体查询来实现吗?

JSFiddle

div {
  box-sizing: border-box;
  margin: 2px;
}

.grid {
  display: flex;
  flex-flow: row wrap;
  border: 2px solid blue;
  flex: 1;
}

.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}
<div class="grid">
  <div class="grid">
    <div class="cell">1</div>
    <div class="cell">2</div>
  </div>
  <div class="grid">
    <div class="cell">3</div>
    <div class="cell">4</div>
  </div>
</div>

编辑:我知道我可以让内部.grid完全不包裹,但我真正想要的是,如果空间非常紧,所有单元格都会彼此包裹。 (如第一个插图所示。)

3 个答案:

答案 0 :(得分:2)

您需要告诉.grid .grid的子元素连续流动:

div {
  box-sizing: border-box;
  margin: 2px;
}

.grid {
  display: flex;
  flex-flow: row wrap;
  border: 2px solid blue;
  flex: 1;
}

.grid .grid {
  flex-flow: row; /* this is your fix */
}

.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}
<div class="grid">
  <div class="grid">
    <div class="cell">1</div>
    <div class="cell">2</div>
  </div>
  <div class="grid">
    <div class="cell">3</div>
    <div class="cell">4</div>
  </div>
</div>

答案 1 :(得分:1)

请注意,没有特定的Flexbox属性可以替换媒体查询,也不需要媒体查询是完美的,比任何其他可用的方法或属性更好。

这里的诀窍是让内部 gridcell之前进行换行。为了实现这一点,他们还需要一个最小宽度,这个宽度比2 cell的总和要宽。

额外min-width的缺点是它还会影响较窄屏幕上cell的宽度

Fiddle demo 1

Stack snippet

&#13;
&#13;
div {
  box-sizing: border-box;
  margin: 2px;
}
.grid-outer {
  display: flex;
  flex-wrap: wrap;
  border: 2px solid blue;
}
.grid-inner {
  flex: 1;
  display: inline-flex;
  flex-wrap: wrap;
  border: 2px solid blue;
  min-width: 210px;
}
.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}
&#13;
<div class="grid-outer">
  <div class="grid-inner">
    <div class="cell">1</div>
    <div class="cell">2</div>
  </div>
  <div class="grid-inner">
    <div class="cell">3</div>
    <div class="cell">4</div>
  </div>
</div>
&#13;
&#13;
&#13;

选项是在外部 grid上删除Flexbox属性,并将内部 grid设置为{{ 1}}让inline-flex随着内容的增长而增长。

这样做的缺点是cell不会填补他们的父母宽度

Fiddle demo 2

Stack snippet

&#13;
&#13;
cell
&#13;
div {
  box-sizing: border-box;
  margin: 2px;
}
.grid-outer {
  display: inline-block;
}
.grid-inner {
  display: inline-flex;
  flex-wrap: wrap;
  border: 2px solid blue;
}
.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}
&#13;
&#13;
&#13;

这里绝对最佳的解决方案是Flexbox和媒体查询的组合,其中一个使用查询将外部 <div class="grid-outer"> <div class="grid-inner"> <div class="cell">1</div> <div class="cell">2</div> </div> <div class="grid-inner"> <div class="cell">3</div> <div class="cell">4</div> </div> </div>的flex方向更改为列。

Fiddle demo

Stack snippet

&#13;
&#13;
grid
&#13;
div {
  box-sizing: border-box;
  margin: 2px;
}
.grid-outer {
  display: flex;
  border: 2px solid blue;
}
.grid-inner {
  flex: 1;
  display: flex;
  border: 2px solid blue;
}
.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}

@media (max-width: 600px) {
  .grid-outer {
    flex-direction: column;
  }
}
&#13;
&#13;
&#13;

...或将内部 <div class="grid-outer"> <div class="grid-inner"> <div class="cell">1</div> <div class="cell">2</div> </div> <div class="grid-inner"> <div class="cell">3</div> <div class="cell">4</div> </div> </div>全部放在一起并更改grid的弹性基础

Fiddle demo

Stack snippet

&#13;
&#13;
cell
&#13;
div {
  box-sizing: border-box;
  margin: 2px;
}
.grid-outer {
  display: flex;
  flex-wrap: wrap;
  border: 2px solid blue;
}
.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}

@media (max-width: 600px) {
  .cell {
    flex-basis: calc(50% - 4px);
  }
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

对网格进行不同的定义可以完成这项工作。我将它们重新定义为外部和内部网格。

编辑:添加.grid-inner的换行以覆盖宽度&lt; 200像素

div {
  box-sizing: border-box;
  margin: 2px;
}

.grid-outer {
  display: flex;
  flex-flow: row wrap;
  border: 2px solid blue;
  flex: 1;
  width: 230px; /* for demo purposes */
}

.grid-inner {
  display: flex;
  border: 2px solid green;
  flex-wrap: wrap;
}

.cell {
  flex: 1;
  min-width: 100px;
  border: 2px solid red;
  background: white;
  height: 100px;
}
<div class="grid-outer">
  <div class="grid-inner">
    <div class="cell">1</div>
    <div class="cell">2</div>
  </div>
  <div class="grid-inner">
    <div class="cell">3</div>
    <div class="cell">4</div>
  </div>
</div>