html - 使用 flexbox 和 hack 之前的嵌套网格布局
问题描述
有人可以解释这个例子是如何工作的吗?
- 为什么在
.content::before
那里使用? - 为什么如果我取消注释第 19 行 (
/* align-items: center; */
) 就全部中断了?
PS:codepen的相同代码
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
*::before, *::after {
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
font: 1rem/1.5 sans-serif;
}
.container {
display: flex;
/* align-items: center; */
justify-content: center;
height: 100%;
max-width: 960px;
margin: auto;
}
.content {
display: flex;
flex-flow: column wrap;
align-content: space-between;
position: relative;
background-color: gold;
}
.content::before, .content::after {
content: '';
flex-basis: 100%;
width: 0;
order: 2;
position: relative;
}
.content::after {
display: none;
}
.content > * {
flex-grow: 1;
flex-shrink: 1;
min-height: 0.0033rem;
}
.a {
width: calc(100% / 3 * 2 + 0.0033rem);
order: 1;
}
.b {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.c {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.a { background: red; }
.b { background: green; }
.c { background: blue; }
.a, .b, .c {
padding: 1rem;
min-height: 120px;
}
<div class="container">
<div class="content">
<div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
<div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
</div>
</div>
解决方案
::before
伪元素
应用于弹性容器的伪元素被认为是弹性项目(MDN)。
因此,该::before
元素是.content
flex 容器中的一个 flex 项。如果::after
pseudo 未设置为display: none
,它也将是 的弹性项目.content
。
简而言之,.content
flex 容器有四个项目,并且伪设置为order: 2
. 所以元素的顺序如下:
<div class="content">
<div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<css pseudo element></css pseudo element>
<div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</div>
伪设置为flex-basis: 100%
。
.content::before {
content: '';
flex-basis: 100%;
width: 0;
order: 2;
position: relative;
}
在列方向容器(即.content
)中,这等价于height: 100%
。
由于容器也设置为wrap
,带有 的项目height: 100%
占据一整列并将后续项目强制到新列。
.container {
display: flex;
/* align-items: center; */
justify-content: center;
height: 100%;
max-width: 960px;
margin: auto;
}
.content {
display: flex;
flex-flow: column wrap;
align-content: space-between;
position: relative;
background-color: gold;
}
.content::before,
.content::after {
content: '';
flex-basis: 100%;
width: 0;
order: 2;
position: relative;
}
.content::after {
display: none;
}
.content>* {
flex-grow: 1;
flex-shrink: 1;
min-height: 0.0033rem;
}
.a {
width: calc(100% / 3 * 2 + 0.0033rem);
order: 1;
}
.b {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.c {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.a {
background: red;
}
.b {
background: green;
}
.c {
background: blue;
}
.a,
.b,
.c {
padding: 1rem;
min-height: 120px;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
font: 1rem/1.5 sans-serif;
}
<div class="container">
<div class="content">
<div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
<div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
</div>
</div>
DOM 元素设置为min-height: 120px
...
.a, .b, .c {
min-height: 120px;
}
...但是它们消耗了容器中的所有高度,因为它们也设置为flex-grow: 1
:
.content > * {
flex-grow: 1;
}
伪列是完全不可见的,因为它设置为width: 0
。
如果,假设您添加了宽度或内容,则由伪创建的列将变得可见:
.container {
display: flex;
/* align-items: center; */
justify-content: center;
height: 100%;
max-width: 960px;
margin: auto;
}
.content {
display: flex;
flex-flow: column wrap;
align-content: space-between;
position: relative;
background-color: gold;
}
.content::before,
.content::after {
content: 'X';
flex-basis: 100%;
/* width: 0; */
order: 2;
position: relative;
}
.content::after {
display: none;
}
.content>* {
flex-grow: 1;
flex-shrink: 1;
min-height: 0.0033rem;
}
.a {
width: calc(100% / 3 * 2 + 0.0033rem);
order: 1;
}
.b {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.c {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.a {
background: red;
}
.b {
background: green;
}
.c {
background: blue;
}
.a,
.b,
.c {
padding: 1rem;
min-height: 120px;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
font: 1rem/1.5 sans-serif;
}
<div class="container">
<div class="content">
<div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
<div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
</div>
</div>
align-items: center
如上所述,align-items: center
在主 flex 容器 ( .container
) 上禁用的布局允许项目.b
&.c
换行,因为::before
伪项目占用了前一列中的所有空间flex-basis: 100%
。视口设置环绕的高度限制和断点。
当您启用align-items: center
时,容器 ( .content
) 通过自由空间的分布垂直居中。不再有身高限制。没有断点告诉项目要包装。所以所有项目(包括伪项目)都保留在一个列中。
.container {
display: flex;
align-items: center; /* enabled */
justify-content: center;
height: 100%;
max-width: 960px;
margin: auto;
}
.content {
display: flex;
flex-flow: column wrap;
align-content: space-between;
position: relative;
background-color: gold;
}
.content::before,
.content::after {
content: 'X';
flex-basis: 100%;
/* width: 0; */
order: 2;
position: relative;
}
.content::after {
display: none;
}
.content>* {
flex-grow: 1;
flex-shrink: 1;
min-height: 0.0033rem;
}
.a {
width: calc(100% / 3 * 2 + 0.0033rem);
order: 1;
}
.b {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.c {
width: calc(100% / 3 * 1 + 0.0033rem);
order: 2;
}
.a {
background: red;
}
.b {
background: green;
}
.c {
background: blue;
}
.a,
.b,
.c {
padding: 1rem;
min-height: 120px;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
font: 1rem/1.5 sans-serif;
}
<div class="container">
<div class="content">
<div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
<div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
<div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
</div>
</div>