布局可以吗?具有多列和多行的 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>
演示
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 容器来实现布局。
- 主 flex 容器
#rFlex
将所有内容包装成一行。
- 垂直右侧包裹在
#cFlex
中,导致 #flex2, #flex3
和 #flex4
在一列中流动。
- 然后弹性项目
#flex3
和#flex4
被设置为水平流动#sFlex
。
#cflex
是 inline-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>
我很好奇这种布局是否适用于 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>
演示
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 容器来实现布局。
- 主 flex 容器
#rFlex
将所有内容包装成一行。 - 垂直右侧包裹在
#cFlex
中,导致#flex2, #flex3
和#flex4
在一列中流动。 - 然后弹性项目
#flex3
和#flex4
被设置为水平流动#sFlex
。 #cflex
是inline-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>