前言
首先我们以一个题目来引出flex属性的使用规则
问题一
如何实现下面图片的效果
首先我们可能会提出一种解决方案
最大的灰色盒子里面包含着三个小盒子,大盒子使用flex布局,然后每个小盒子设置属性flex: 1; 这样即可完成图片效果。代码如下(代码1)
<style>
.main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
background-color: darkgray;
padding: 15px;
height: 60px;
}
.main :nth-child(2) {
margin: 0 15px;
}
.item {
flex: 1;
background-color: darkmagenta;
height: 100%;
}
</style>
<div class="main">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
确实是实现了上图的效果
上面的问题很简单,其实也就是flex的基本使用,下面来另外的一个问题
问题二
如何实现下面的效果(前提:最下面的一行只能存在两个子盒子红色和黄色,而且这两个子盒子里面不能有任何内容,里面不能再嵌套任何节点标签)注意里面深灰色的间隙的宽度都为15px
你可能很直接的想到下面两种布局方式
方式一
将整个模块分为上下两行,第一行使用flex布局,然后每个子盒子flex:1,第二行第一个子盒子占一份所以设置属性flex:1,第二个子盒子占两份所以flex属性设置为2,如下图所示
代码如下(代码2)
<style>
.flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.main {
padding: 15px;
background-color: silver;
}
.upitem {
flex: 1;
height: 100px;
background-color: skyblue;
}
.up :nth-child(2) {
margin: 0 15px;
}
.bottom {
height: 100px;
margin-top: 15px;
}
.bottomitem1 {
flex: 1;
height: 100%;
background-color: bisque;
}
.bottomitem2 {
flex: 2;
height: 100%;
background-color: red;
}
</style>
<div class="main">
<div class="up flex">
<div class="upitem"></div>
<div class="upitem"></div>
<div class="upitem"></div>
</div>
<div class="bottom flex">
<div class="bottomitem1"></div>
<div class="bottomitem2"></div>
</div>
</div>
但是效果却是下图所示
我们试着直接在红色的盒子加上margin-left: 15px;或者在黄色盒子加上margin-right: 15px;效果如下
很明显还是不能满足要求
最后发现无论怎么设置padding和margin还是不能实现题目的效果
方式二
方式二可能是直接将这五个盒子分成两列(而不是上面的两行)然后第一列flex:1; 第二列flex:2; 很明显这样的方式还是不行的,其实这种方式和方式一的第二行的是一样的,是无法达到绝对的平均分(也就是红色一边占两份,另外黄色一边占一份)
那么该如何解决呢?
实际上无法解决问题二主要是由于我们对flex属性的不了解所致,打开MDN搜素flex属性,你会发现他是三个属性的简写形式,如下图
我们一般只在flex后面写一个值其实就是下面的单值语法中的第一种方式(一个无单位的数)
下面我们来看看这三个属性都是什么作用
先看grow,下面是官方解析
说白了就是剩余空间的分配比例
既然是剩余空间,那么什么是非剩余的空间呢?flex-basis属性的值就是占有非剩余空间的
我们来试想一下如何利用非剩余空间来解决问题二
我们先稍微的修改一下代码2,将黄色盒子的flex: 1属性改为flex-basis: 0px; 然后将红色盒子的flex: 2属性改为flex-basis: 15px;和margin-left: 15px;
代码如下(代码3)
<style>
.flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.main {
padding: 15px;
background-color: silver;
}
.upitem {
flex: 1;
height: 100px;
background-color: skyblue;
}
.up :nth-child(2) {
margin: 0 15px;
}
.bottom {
height: 100px;
margin-top: 15px;
}
.bottomitem1 {
/* 非剩余空间占0px */
flex-basis: 0px;
height: 100%;
background-color: bisque;
}
.bottomitem2 {
/* 非剩余空间占15px */
flex-basis: 15px;
/* margin设置为15px 用作效果图上面的深灰色隔离区域 */
margin-left: 15px;
height: 100%;
background-color: red;
}
</style>
<div class="main">
<div class="up flex">
<div class="upitem"></div>
<div class="upitem"></div>
<div class="upitem"></div>
</div>
<div class="bottom flex">
<div class="bottomitem1"></div>
<div class="bottomitem2"></div>
</div>
</div>
效果如下
可以看到即使我们没有为这两个盒子设置width属性他们还是存在自己的宽度,黄色盒子的宽度为0,而红色盒子的宽度为15px,这个宽度是通过flex-basis属性来设置的(注意上图鼠标左侧的黄色区域不是盒子1只是控制台显示的盒子二的margin的宽度而已),这就是flex-basis的作用
此时剩余空间就是下面括号的范围
而非剩余空间也就是红色盒子的宽度和其margin刚好占满了两份深灰色的间隙,也就是说非剩余空间现在刚好可以分成完全均等的三份,此时我们只需要将两份分给红色盒子,一份分给黄色盒子即可
代码如下
<style>
.flex {
display: flex;
justify-content: space-between;
align-items: center;
}
.main {
/* height: 400px; */
padding: 15px;
background-color: silver;
}
.upitem {
flex: 1;
height: 100px;
background-color: skyblue;
}
.up :nth-child(2) {
margin: 0 15px;
}
.bottom {
height: 100px;
margin-top: 15px;
}
.bottomitem1 {
/* 剩余空间占一份 */
flex-grow: 1;
/* 非剩余空间占0px */
flex-basis: 0px;
height: 100%;
background-color: bisque;
}
.bottomitem2 {
/* 剩余空间占两份 */
flex-grow: 2;
/* 非剩余空间占15px */
flex-basis: 15px;
/* margin设置为15px */
margin-left: 15px;
height: 100%;
background-color: red;
}
</style>
<div class="main">
<div class="up flex">
<div class="upitem"></div>
<div class="upitem"></div>
<div class="upitem"></div>
</div>
<div class="bottom flex">
<div class="bottomitem1"></div>
<div class="bottomitem2"></div>
</div>
</div>
效果如下
这样就解决了问题二了
至于什么是flex-shrink这个自行了解一下即可