首页 文章

Flexbox包装嵌套行而不进行媒体查询

提问于
浏览
4

我在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 's instead of considering them rows. In order to keep all of the other wrapping working, setting flex-basis (to e.g. 100%) for the nested div' s不是一个选项 . 为了保持一切动态(例如将第三个单元格添加到其中一个行),在单元格上设置%-widths不是一个选项 . 并且为了避免硬断点和基本包装(动态)内容宽度,我真的想避免媒体查询 .

Can this be achieved with flexbox and without media queries?

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>

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

3 回答

  • 1

    你需要告诉 .grid .grid 的children元素连续流动:

    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>
    
  • 0

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

    这里的诀窍是让内部 grid 在_1596800之前进行换行 . 为了实现这一点,他们还需要一个最小宽度,这个宽度比2 _1596801的总宽度要宽 .

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

    Fiddle demo 1

    堆栈代码段

    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;
    }
    
    <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 上删除Flexbox属性,并将内部 grid 设置为 inline-flex ,让 cell 随其内容一起增长 .

    这样的缺点是 cell 's won't填充他们的父母宽度

    Fiddle demo 2

    堆栈代码段

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

    这里绝对最好的解决方案是Flexbox和媒体查询的组合,其中一个使用查询将外部 grid 的弹性方向改为列...

    Fiddle demo

    堆栈代码段

    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;
      }
    }
    
    <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 全部放在一起并改变 cell 的弹性基础

    Fiddle demo

    堆栈代码段

    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);
      }
    }
    
    <div class="grid-outer">
        <div class="cell">1</div>
        <div class="cell">2</div>
        <div class="cell">3</div>
        <div class="cell">4</div>
    </div>
    
  • 2

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

    编辑:为 .grid-inner 添加了包裹,以覆盖宽度<200px

    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>
    

相关问题