弹性盒简介
弹性盒(Flex Box)是 CSS3 的一种新的布局模式,是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间
弹性盒父元素叫容器,子元素叫项目,水平方向叫主轴,垂直方向叫侧轴,弹性盒作用就是让容器有能力去控制项目的位置、大小、顺序、方向等等
弹性盒的使用
创建html文件
父盒子father-box,子盒子son-one,son-two,son-third
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弹性盒</title> <style> .father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; } .son-third { width: 100px; height: 100px; background-color: brown; } </style> </head> <body> <div class="father-box"> <div class="son-one"></div> <div class="son-two"></div> <div class="son-third"></div> </div> </body> </html>
定义一个弹性盒
使用弹性盒的前提是我们必须先定义一个弹性盒,给父元素添加属性display: flex;当父元素定义成弹性盒之后,子元素会默认横向排列(水平排列)
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; }
弹性盒的对齐方式
justify-content
父元素设置justify-content: 子元素沿主轴(X轴-水平)对齐方式
- 备注:(不能忽视margin,margin算已占用的空间,margin不算剩余空间,即就算是设置了弹性盒,父元素和子元素之前设置的margin也是生效的)
justify-content有以下属性:
- flex-start:子元素向一行的起始位置(最左)靠齐。
- flex-end:子元素向一行的结束位置(最右)靠齐;
- center:子元素向一行的中间位置靠齐;
- space-between:子元素会平均的分布在行里;
- space-around:子元素会平均的分布在行里,两端保留项目间距的一半的剩余空间;
align-items
父元素设置align-items: 子元素沿侧轴(Y轴-垂直)对齐方式
- 备注:(不能忽视margin,margin算已占用的空间,margin不算剩余空间,即就算是设置了弹性盒,父元素和子元素之前设置的margin也是生效的)
align-items有以下属性:
- flex-start:子元素在侧轴起点边的外边距 紧靠住 该行在侧轴起始边(顶部);
- flex-end:子元素在侧轴终点边的外边距 紧靠住 该行在侧轴终点边(底部);
- center:子元素的外边距盒 在该行的侧轴上居中放置;
- stretch(默认值):子元素拉伸填充整个父盒子容器。子元素拉伸填充整个伸缩容器(不能忽视margin算已占用的空间,margin不算剩余空间);弹性盒布局默认是可以拉伸元素的(子盒子纵向排列的时候,元素没有设置宽度拉伸的是宽(充满容器),子盒子横向排列的时候没有设置高度,默认拉伸高(充满容器的高度))。(stretch必须要是在纵向排列时子盒子没有设置宽度而设置了高度,这样才会拉伸子盒子的宽度占满剩余空间;或者在横向排列时子盒子设置了宽度而没有设置高度,这样才会拉伸子盒子的高度占满剩余空间)(stertch如果在子盒子宽高都设置了的情况下不会拉伸)(如果盒子设置了宽高,stretch作用,不会拉伸,默认停留在原位置)
- 子元素宽高都设置的情况下
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; align-items: stretch; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; } .son-third { width: 100px; height: 100px; background-color: brown; }
- 子元素横向排列,只设置了宽度不设置高度的情况下
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; align-items: stretch; } .son-one { width: 100px; background-color: yellow; } .son-two { width: 100px; background-color: black; } .son-third { width: 100px; background-color: brown; }
- 子元素纵向排列,只设置高度不设置宽度的情况下
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; align-items: stretch; flex-direction: column; // 让子元素纵向排列 } .son-one { height: 100px; background-color: yellow; } .son-two { height: 100px; background-color: black; } .son-third { height: 100px; background-color: brown; }
5. baseline:子元素根据子元素的基线对齐;默认以(高度或宽度)值大的为标准(有文字的盒子,基线以文字的底部为准,没有文字的,基线以盒子的底部为准)(不能忽视margin算已占用的空间,margin不算剩余空间);
- 子元素无文字的情况
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; align-items: baseline; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 200px; background-color: black; } .son-third { width: 100px; height: 300px; background-color: brown; }
- 子元素内容有文字的情况
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弹性盒</title> <style> .father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; align-items: baseline; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 200px; background-color: black; color: #fff; } .son-third { width: 100px; height: 300px; background-color: brown; } </style> </head> <body> <div class="father-box"> <div class="son-one">1</div> <div class="son-two">2</div> <div class="son-third">3</div> </div> </body> </html>
排列方向 flex-direction
父元素设置flex-direction,可以设置子元素的排列方向为水平还是纵向,是正序还是反序
flex-direction有以下值:
- row:子元素从左向右排列
- row-reverse:从右到左排列(反序);
- column:从上到下
- column-reverse:从下到上排列(反序);
flex 设置弹性盒子的子元素如何分配空间
子元素设置flex属性,决定了子元素如何分配剩余空间
什么是剩余空间
如果子元素是横向排列,那么剩余空间就是父盒子的宽度-子盒子的宽度-子盒子的水平margin
如果子元素是纵向排列,那么剩余空间就是父盒子的高度-子盒子的高度-子盒子的垂直margin
- 如果只有一个子元素设置flex,其他元素不设置flex,那么这个子元素将根据排列方向,横向或者纵向拉伸(拉伸宽度或者高度),占满父元素的剩余空间
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; } .son-one { width: 100px; height: 100px; background-color: yellow; flex: 1; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; }
- 如果有多个子元素设置了flex,那么设置了flex的元素将等比例分配剩余空间,根据排列方向,横向或者纵向拉伸(拉伸宽度或者高度),占满父元素的剩余空间
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; } .son-one { width: 100px; height: 100px; background-color: yellow; flex: 1; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; flex: 2; } .son-third { width: 100px; height: 100px; background-color: brown; flex: 3; }
order 设置弹性盒子的子元素排列顺序
子元素设置了order属性,将决定子元素在父元素内的排列顺序
不定义order的伸缩项目会排到最前面
order:1; 排第一
order:2; 排第二
(意思就是比如有三个盒子A/B/C,标准流中A/B/C依次向下编写,但是在父盒子设置了弹性盒后,C不设置order,A设置order:1,B设置order:2,然后显示顺序就是C排最前面,A排第二,B排第三,order值越高,排越后面)
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; } .son-one { width: 100px; height: 100px; background-color: yellow; order: 1; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; order: 2; } .son-third { width: 100px; height: 100px; background-color: brown; }
flex-wrap 设置弹性盒子的子元素超出父容器时是否换行
默认情况下,弹性盒内的子元素如果总宽度(水平排列)或者总高度(垂直排列)超过父盒子,那么子元素将被压缩宽度(或高度),使所有的子元素在同一行或者同一列。
我们可以给父元素设置 flex-wrap,让其换行或者换列
flex-wrap有以下属性
- nowrap 默认情况下的场景,不换行,不管子盒子的总宽度(高度)超出父盒子宽度(高度)还是不超出都不会换行(列),如果超出了父盒子宽度(高度),子盒子即使设置了宽度(高度)也会被压缩
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弹性盒</title> <style> .father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; } </style> </head> <body> <div class="father-box"> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-one">1</div> <div class="son-two">2</div> <div class="son-third">3</div> </div> </body> </html>
- wrap 换行,一旦伸缩项目超出伸缩容器,那么就会换行(列),此时子元素不会被压缩,仍保留原来的宽度(高度),但是wrap换行会有默认行距(列距)
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; flex-wrap: wrap; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; }
- wrap-reverse 换行反向 主轴水平时,上下反向,主轴垂直时,左右反向;即水平时,第一行会变成最后一行;垂直时,第一列会变成最后一列
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; flex-wrap: wrap-reverse; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; }
align-content 修改 flex-wrap 属性的行为
align-content修改 flex-wrap 属性的行为,类似 align-items, 但不是设置子元素对齐,而是设置行对齐。
比如当父元素有高度(宽度)时,子元素换行(列)后会有行距(列距)(父盒子没高度,换行就没行距,父盒子没宽度,换列就没列距,),给父元素设置align-centent可以取消行距(列距)
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; flex-wrap: wrap; align-content: flex-start; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; }
排列方向 flex-direction与换行(列) flex-flow 缩写形式
flex-direction与 flex-flow两个属性可以缩写成一个属性flex-flow
flex-flow:flex-direction flex-wrap; 两个值同时定义或者单独定义都生效
如 flex-flow: wrap和 flex-flow:column wrap;
.father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; flex-flow:column wrap; align-content: flex-start; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; }
弹性盒多属性之间的相互配合
比如我们可以justify-content和align-items相互配合实现子元素的水平垂直居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弹性盒</title> <style> .father-box { width: 500px; height: 500px; border: 1px solid red; margin: 100px auto 0; display: flex; justify-content: center; align-items: center; } .son-one { width: 100px; height: 100px; background-color: yellow; } .son-two { width: 100px; height: 100px; background-color: black; color: #fff; } .son-third { width: 100px; height: 100px; background-color: brown; } </style> </head> <body> <div class="father-box"> <div class="son-one">1</div> <div class="son-two">2</div> <div class="son-third">3</div> </div> </body> </html>