介绍:
- flex布局也称为弹性布局,顾名思义,他会随着客户端不同设备的屏幕大小自动伸展或收缩盒子,
- flex布局是一种一维布局模型,因为一个flex盒子一次只能处理一行或一列的元素布局,grid布局才是二维布局,可以同时处理行和列上的布局。
- flex布局默认不会换行,意思是在一个维度中他的子盒子溢出后,会将子盒子进行压缩,实在压缩不了的就溢出屏幕了;设置自动换行后,新的行就相当于一个新的flex盒子。
一、如何将盒子设置为flex布局模式
在盒子的css样式中添加 display: flex; 。意思就是你给一个盒子的样式添加了flex布局后,这个盒子的所有子盒子都会按照flex的布局规则来显示。
<div class="box">
<div>子盒子1</div>
<div>子盒子2</div>
<div>子盒子3</div>
</div>
/* 父元素样式 */
.box {
padding: 5px;
background-color: yellow;
border: 2px dotted rgb(96 139 168);
height: 50px;
/* 将display属性的值设置为flex */
display: flex;
}
/* 所有子元素样式 */
.box > * {
background-color: red;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
}
flex布局默认在一行上显示,会将子盒子自动转为行内块模式
二、flex布局的两根轴线
1、概念
意思就是使用flex布局后,子盒子排列(延展)的方向就是主轴,与主轴垂直的方向就是交叉轴(侧轴);拿空间直角坐标系来说,默认情况下,主轴就是x轴,交叉轴就是y轴;默认情况下,主轴的排列方向是x轴的正方向,交叉轴的排列方向是y轴的负方向。
2、使用 flex-direction 属性改变主轴的方向
flex-direction属性的属性值有 4 个,给父盒子设置:
- row 主轴为x轴,子盒子向x轴的正方向排列(默认方向)
/* 父元素样式 */
.box {
/* 将display属性的值设置为flex */
display: flex;
/* 默认就是row,子盒子从左往右排列 */
flex-direction: row;
}
- row-reverse 主轴为x轴,子盒子向x轴的负方向排列
/* 父元素样式 */
.box {
/* 将display属性的值设置为flex */
display: flex;
/* 子盒子从右往左排列 */
flex-direction: row-reverse;
}
- column 主轴变为y轴,子盒子向y轴的负方向排列
/* 父元素样式 */
.box {
/* 将display属性的值设置为flex */
display: flex;
/* 主轴变为y轴,子盒子向y轴的负方向排列 */
flex-direction: column;
}
- column-reverse 主轴变为y轴,子盒子向y轴的正方向排列
/* 父元素样式 */
.box {
/* 将display属性的值设置为flex */
display: flex;
/* 主轴变为y轴,子盒子向y轴的正方向排列 */
flex-direction: column-reverse;
}
3、使用flex-wrap 属性控制主轴上盒子溢出换行
flex-wrap 的属性值有2个,分别是 nowrap 和 wrap,默认为flex-wrap: nowrap; 不换行
给父盒子设置
例子:
- 父盒子总宽度为500px,每个子盒子宽度为100px,有五个子盒子刚好分配完父盒子空间
<div class="box">
<div>子盒子1</div>
<div>子盒子2</div>
<div>子盒子3</div>
<div>子盒子4</div>
<div>子盒子5</div>
</div>
/* 父元素样式 */
.box {
padding: 5px 0;
background-color: yellow;
border: 2px dotted rgb(96 139 168);
height: 100px;
/* 父盒子总宽度为500px */
width: 500px;
/* 将display属性的值设置为flex */
display: flex;
}
/* 所有子元素样式 */
.box > * {
box-sizing: border-box;
background-color: red;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
/* 每个子盒子宽为100px */
width: 100px;
}
- 在上个例子的基础上,子盒子数量从5个变为6个,子盒子总宽度大于父盒子宽度,但是flex布局默认不允许换行,所以子盒子会被压缩,此时每个子盒子宽度为 500/6
- 在上个例子的基础上,给父盒子添加 flex-wrap: wrap;
/* 父元素样式 */
.box {
padding: 5px 0;
background-color: yellow;
border: 2px dotted rgb(96 139 168);
height: 100px;
/* 父盒子总宽度为500px */
width: 500px;
/* 将display属性的值设置为flex */
display: flex;
/* 给父盒子设置成允许换行 */
flex-wrap: wrap;
}
4、flex-direction 和 flex-wrap 组合简写为flex-flow
flex-flow 属性第一个属性值表示 flex-direction,第二个属性值表示 flex-wrap,给父盒子设置
例子:flex-flow: row-reverse wrap;
<div class="box">
<div>子盒子1</div>
<div>子盒子2</div>
<div>子盒子3</div>
<div>子盒子4</div>
<div>子盒子5</div>
<div>子盒子6</div>
</div>
/* 父元素样式 */
.box {
padding: 5px 0;
background-color: yellow;
border: 2px dotted rgb(96 139 168);
height: 100px;
width: 500px;
display: flex;
/* 原来的写法
flex-direction: row-reverse;
flex-wrap: wrap; */
/* 组合缩写 */
flex-flow: row-reverse wrap;
}
/* 所有子元素样式 */
.box > * {
box-sizing: border-box;
background-color: red;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
width: 100px;
}
三、flex元素上的属性
前情概要:剩余空间
剩余空间是指,比如说父盒子宽度为500px,他有3个子盒子,每个子盒子的宽度为100px,那么父盒子的空间除了三个子盒子占的300px之外,还有200px,这200px的空间就是剩余空间
1、flex-basis
- flex-basis 属性就相当于 css样式的 width 属性,用来指定盒子的宽度
- 如果一个元素同时被设置了 flex-basis 和 width ,则 flex-basis 的优先级更高
- 如果一个元素没有给定尺寸,则 flex-basis 属性的值为元素内容的尺寸
/* 所有子元素样式 */
.box > * {
/* 优先级更高 */
flex-basis: 50px;
width: 100px;
}
2、flex-grow
- flex-grow 属性的属性值是一个正整数
- 功能是在 flex-basis 的值的基础上,分配父盒子的剩余空间,沿主轴排列方向伸展
- 如果只有一个子盒子设置flex-grow属性,则剩余空间都是这个子盒子的,如果其他子盒子也设置了flex-grow属性,则设置了flex-grow属性的子盒子们按所设置的比例(flex-grow的属性值)分配剩余空间
初始代码和结果:
<div class="box">
<div class="one">子盒子1</div>
<div class="two">子盒子2</div>
<div class="three">子盒子3</div>
</div>
/* 父元素样式 */
.box {
padding: 5px 0;
background-color: yellow;
border: 2px dotted rgb(96 139 168);
height: 100px;
/* 父盒子总宽度为500px */
width: 500px;
/* 将display属性的值设置为flex */
display: flex;
}
/* 所有子元素基础样式 */
.box > * {
box-sizing: border-box;
background-color: red;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
/* 每个子盒子宽为100px */
width: 100px;
}
- 只有子盒子1设置了flex-grow
.one{
/* 只有一个盒子设置的情况下,他的属性值为多少都无所谓,剩余空间都是他的 */
flex-grow: 1;
}
- 三个子盒子都设置了flex-grow,但是所占比例不一样
/* 将剩余空间分成了4份 */
.one{
/* 占1份 */
flex-grow: 1;
}
.two{
/* 占2份 */
flex-grow: 2;
}
.three{
/* 占1份 */
flex-grow: 1;
}
3、flex-shrink
- flex-shrink 属性的属性值是一个正整数
- 功能和flex-grow相反,flex-shrink是当子盒子溢出时,按比例收缩
- flex-shrink 属性默认是开启的,且每个子盒子都被设置为 flex-shrink: 1;
例子:其他盒子默认值按多处空间的 1 份压缩,盒子1设置为按多处空间的 2 份压缩
.one{
flex-shrink: 2;
}
4、flex属性的简写(最常用)
在实际开发中很少直接写flex-basis、flex-grow、flex-shrink,都是使用简写形式,一般给子盒子设置
例如:第一个值表示 flex-grow,第二个值表示 flex-shrink,第三个值表示 flex-basis
.one{
flex: 1 1 auto;
}
常见的写法:
flex: initial(相当于
flex: 0 1 auto)
flex: auto(相当于
flex: 1 1 auto)
flex: none(相当于
flex: 0 0 auto)
flex: <positive-number>
对于 flex:<positive-number> 展开来说(最常用):
我们常看到的 flex: 1
或者 flex: 2
等等。它相当于flex: 1 1 0
或者 flex: 2 1 0
。元素不设置 flex-basis
,而是根据设置的伸展比例,自动分配父盒子的空间,这就是弹性布局的由来,在不同屏幕上,盒子的大小自适应。
四、元素的对齐和剩余空间分配
1、justify-content(主轴上的对齐)
实现主轴上的子元素的对齐,justify-content 给父盒子设置
- justify-content: start(子盒子在主轴开头对齐)
- justify-content: end(子盒子在主轴结尾对齐)
- justify-content: center(子盒子在主轴中间对齐)
- justify-content: space-between(将剩余空间平均分配给盒子之间)
- justify-content: space-around(将剩余空间环绕盒子分配)
- justify-content: space-evenly(将剩余空间平均分配给盒子周围)
2、align-items(交叉轴上的对齐)
作用是使一个维度上的所有子元素在交叉轴方向上实现对其,align-items 给父盒子设置
- align-items: stretch(默认,子盒子不设置高度的话,就会被拉伸到和父级高度一样)
- align-items: start(子盒子按flex容器的顶部对齐)
- align-items: end(子盒子按flex容器的底部对齐)
- align-items: center(子盒子在flex容器的中间对齐)
3、align-self(交叉轴上的对齐)
align-items是控制一个维度上的全部子盒子的对齐,align-self是控制一个维度上的单个子盒子的对齐,align-self 给对应的子盒子设置
- align-self: stretch
- align-self: start
- align-self: end
- align-self: center
<div class="box">
<div class="one">子盒子1</div>
<div class="two">子盒子2</div>
<div class="three">子盒子3</div>
<div class="four">子盒子4</div>
</div>
.one{
align-self: stretch;
}
.two{
align-self: start;
}
.three{
align-self: end;
}
.four{
align-self: center;
}
4、align-content(交叉轴上的对齐)
只有一行flex容器时,align-content 的效果和 align-items 的效果一样,这里演示多行的,align-content 给父盒子设置
- align-content: stretch(每行的子盒子都伸展开)
- align-content: start(在交叉轴开头)
- align-content: end(在交叉轴尾部)
- align-content: center(在交叉轴中间)
- align-content: space-between(将交叉轴方向的剩余空间平均分配到盒子之间)
- align-content: space-around(将交叉轴方向的剩余空间环绕盒子分配)
- align-content: space-evenly(将交叉轴方向的剩余空间平均分配到盒子周围)