弹性盒子可以帮助建立弹性布局,可以使得元素在父内容中垂直居中,或者让子元素把父内容填满而不需要计算子元素的尺寸等。
一个例子
受挤压的flex元素
<html>
<head></head>
<body>
<div class="parent flex">
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
</div>
</body>
</html>
.parent {
width: 350px;
border: solid 1px black;
}
.flex {
display: flex;
gap: 10px;
}
.div-block {
background: gray;
width: 100px;
height: 100px;
margin: 5px;
padding: 5px;
}
可以看到此时由于给父容器设置了固定的宽度(350px),内部排列的子元素的实际宽度只有52px,并不是原先设置的100px的固定宽度。
有内容的话…
如果子元素中放了有宽度的内容(比如文字),情况又会不一样。下面这个例子可以看到,子元素中有文字的会先将文字按照词汇宽度折得不能再折,保留最宽的那个单词的尺寸(word-break:break-word
),其他没有内容的子元素将继续被挤压,靠margin
(外边距)和padding
(内边距)撑着,最右侧的子元素去掉了内外边距后直接被挤没了(宽度显示为0)。
如果此时将子元素的word-break
设置为break-all
,则文字可以从任何地方折叠,不会再撑开外壳,子元素的尺寸就又恢复到按照flex容器分布:
想要不被挤压
所以我们可以知道,在flex容器内部子元素的尺寸会受到父容器的挤压,如果想要子元素完整地展示出来,有两种办法:
- 给子元素加上最小宽度/高度,
min-width
或max-width
的优先级高于width
,因此可以不受父容器的布局影响
.div-block {
background: gray;
width: 100px;
height: 100px;
margin: 5px;
padding: 5px;
min-width: 100px; /* 增加尺寸限制 */
}
此时容器内容可能溢出,可以同时在父容器中添加overflow的选项,对溢出做处理:
.parent {
width: 350px;
border: solid 1px black;
overflow-x: auto; /* 如果有溢出会显示滚动条,没有溢出则不显示 */
}
- 给父容器增加wrap选项,允许一行放不下的子元素换行排列
.flex {
display: flex;
gap: 10px;
flex-wrap: wrap; /* 一行放不下就换行 */
}
对flex选项的理解
flex:1
的操作可以让元素弹性地充满容器,flex
选项包含flex-grow
(元素尺寸弹性变化时的比例)、flex-shrink
(当元素超出容器时的收缩比例)、flex-basis
(当有可分配空间时为元素分配的最小尺寸)。
flex-grow 和 flex-basis
写flex:1
,默认赋值flex-grow:1
,子元素将等比例拉伸填充父容器。
写flex:1 40px
,默认赋值flex-grow:1
,flex-basis:40px
,父容器分配完flex-basis指定的尺寸后,剩下的空间由其余的子元素拉伸填充
.flex {
display: flex;
gap: 10px;
/* flex-wrap: wrap; */ /* 关掉容器的wrap,观察挤压情况 */
}
.div-block {
background: gray;
height: 100px;
margin: 5px;
padding: 5px;
flex: 1 10px;
word-break: break-all;
}
<html>
<head></head>
<body>
<div class="parent flex">
<!-- 单独为这个元素设置拉伸系数 -->
<div class="div-block" style="flex-grow: 3;"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block">
</div>
</div>
</body>
</html>
可以看到在分配完每个10px的尺寸后,元素拉伸填充整个父容器,但第一个元素拉伸比例(flex-grow: 3
)大于其他的(flex-grow: 1
)。
flex-shrink
.flex {
display: flex;
gap: 10px;
/* flex-wrap: wrap; */ /* 关掉容器的wrap,观察挤压情况 */
}
.div-block {
background: gray;
height: 100px;
margin: 5px;
padding: 5px;
flex-basis: 40px; /* 父容器先按照40px分配元素,不够的就挤一挤 */
flex-shrink: 1; /* 默认的收缩率 */
word-break: break-all;
}
<html>
<head></head>
<body>
<div class="parent flex">
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<div class="div-block"></div>
<!-- 单独为这个元素设置不同的收缩率 -->
<div class="div-block" style="flex-shrink: 3;">
</div>
</div>
</body>
</html>
可以看到最后一个元素的收缩率大于前面的5个。