布局可以吗?具有多列和多行的 Flexbox 与 Float 布局

Layout possible? Flexbox vs Float layout with multiple columns and rows

我很好奇这种布局是否适用于 flexbox。我似乎无法计算出 divs 3 和 4 属于#2。这对于浮动来说非常容易,只是好奇我是否遗漏了一些可能对 flexbox 有帮助的属性。

布局

+-------+-------+-------+
| div 1 |     div 2     |
+       +-------+-------+
|       | div 3 | div 4 |
+-------+-------+-------+

标记

<div class="features">
  <div class="feature feature-1">1</div>
  <div class="feature feature-2">2</div>
  <div class="feature feature-3">3</div>
  <div class="feature feature-4">4</div>
</div>

演示

http://codepen.io/mikevoermans/pen/xbWvJJ?editors=110

Flexbox 不喜欢扩展到多列或多行的 flex 项目,因为实际上 flexbox 没有网格概念。

但是,使用一些技巧,您可以实现此布局():

  • 使用行布局

    ┌─┬─┬─┬─┐
    │1│2│3│4│
    └─┴─┴─┴─┘
    
  • 允许使用 flex-wrap: wrap 换行。

  • 使用伪元素强制在2后换行

    ┌─┬─┐
    │1│2│
    ├─┼─┤
    │3│4│
    └─┴─┘
    
  • 对所有弹性项目使用 flex: 1

    ┌─────────┬─────────┐
    │1        │2        │
    ├─────────┼─────────┤
    │3        │4        │
    └─────────┴─────────┘
    
  • margin-left: 50% 设置为 3

    ┌─────────┬─────────┐
    │1        │2        │
    └─────────┼────┬────┤
              │3   │4   │
              └────┴────┘
    
  • height: 200px 设置为 2、3 和 4。将 height: 400px 设置为 1。

    ┌─────────┬─────────┐
    │1        │2        │
    │         ├─────────┘
    │         │
    └─────────┼────┬────┐
              │3   │4   │
              └────┴────┘
    
  • margin-bottom: -200px设为1:

    ┌─────────┬─────────┐
    │1        │2        │
    │         ├────┬────┤
    │         │3   │4   │
    └─────────┴────┴────┘
    
  • 因为你有边框,所以在所有框上使用 box-sizing: border-box 使 height 包含边框。否则 1 需要 height: 416px; margin-bottom: -216px.

  • 注意 flexbox 引入 auto 作为 min-width 的新初始值。这可能会让内容迫使一些盒子变大。这会破坏布局,因此使用 min-width: 0 禁用它或将 overflow 设置为除 visible.

  • 之外的任何内容

代码如下:

.features {
  display: flex;
  flex-flow: row wrap;
}
.feature {
  background: #ccc;
  border: 8px solid #fff;
  height: 200px;
  box-sizing: border-box;
  min-width: 0;
  flex: 1;
}
.feature-1 {
  /* Make it taller without increasing the height of the flex line */
  height: 400px;
  margin-bottom: -200px;
}
.features:after {
  /* Force line break */
  content: '';
  width: 100%;
}
.feature-2 ~ .feature {
  /* Place 3 and 4 after the line break */
  order: 1;
}
.feature-3 {
  margin-left: 50%;
}
<div class="features">
  <div class="feature feature-1">1</div>
  <div class="feature feature-2">2</div>
  <div class="feature feature-3">3</div>
  <div class="feature feature-4">4</div>
</div>

但是,修改 HTML 以获得嵌套的 flexbox 会更容易。

#wrapper {
  height: 400px;
}
.flex {
  display: flex;
}
.column {
  flex-direction: column;
}
.flex > div {
  min-width: 0;
  flex: 1;
}
.item {
  background: #ccc;
  border: 8px solid #fff;
}
<div id="wrapper" class="flex row">
  <div class="item">1</div>
  <div class="flex column">
    <div class="item">2</div>
    <div class="flex row">
      <div class="item">3</div>
      <div class="item">4</div>
    </div>
  </div>
</div>

弹性盒不可能,但 CSS 网格可能。 它尚未随所有主要浏览器一起提供,但有一个 polyfill:

https://jsfiddle.net/hvdq63ah/

.features {
    display: grid;
    grid-template-areas:
      "feature1 feature2 feature2"
      "feature1 feature3 feature4";
    grid-template-columns: auto minmax(min-content, 1fr) minmax(min-content, 1fr);
    grid-template-rows: auto minmax(min-content, 1fr);      
      
  background-color: #fff;
}

.feature-1    { grid-area: feature1 }
.feature-2    { grid-area: feature2 }
.feature-3    { grid-area: feature3 }
.feature-4    { grid-area: feature4 }

.feature {
  border: 1px solid black;
  padding: 20px;
}
<div class="features">
  <div class="feature feature-1">1</div>
  <div class="feature feature-2">2</div>
  <div class="feature feature-3">3</div>
  <div class="feature feature-4">4</div>
</div>

使用 flexbox 可以很容易地通过使用三个 flex 容器来实现布局。

  1. 主 flex 容器 #rFlex 将所有内容包装成一行。
  2. 垂直右侧包裹在 #cFlex 中,导致 #flex2, #flex3#flex4 在一列中流动。
  3. 然后弹性项目#flex3#flex4被设置为水平流动#sFlex
  4. #cflexinline-flex 所以它可以稳固地紧挨着 #flex1

html {
  box-sizing: border-box;
  font: 400 16px/1.45'Source Code Pro';
}
*,
*:before,
*:after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
}
body {
  background: #121;
  color: #FEF;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  position: relative;
  width: 100vw;
  height: 100vh;
}
/* Flex Containers */

#rFlex {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;
  -webkit-justify-content: center;
  justify-content: center;
  width: -moz-fit-content;
  width: -webkit-fit-content;
  width: fit-content;
  height: auto;
}
#cflex {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-flex-flow: column wrap;
  flex-flow: column wrap;
  -webkit-justify-content: flex-start;
  justify-content: flex-start;
  -webkit-align-items: center;
  align-items: center;
  height: 80vh;
  width: 45vw;
}
#sFlex {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-flex-flow: row nowrap;
  flex-flow: row nowrap;
  -webkit-justify-content: center;
  justify-content: center;
}
/* Flex Items */

.flex {
  -webkit-flex: 0 0 auto;
  flex: 0 0 auto;
}
#flex1 {
  width: 45vw;
  height: 80vh;
  background: red;
}
#flex2 {
  width: 45vw;
  height: 40vh;
  background: blue;
}
#flex3,
#flex4 {
  width: 22.5vw;
  height: 40vh;
}
#flex3 {
  background: yellow;
}
#flex4 {
  background: green;
}
<main id="rFlex">
  <section id="flex1" class="flex">

  </section>
  <article id="cFlex">
    <section id="flex2" class="flex">

    </section>
    <aside id="sFlex">
      <section id="flex3" class="flex">

      </section>
      <section id="flex4" class="flex">

      </section>
    </aside>
  </article>
</main>