父容器
在正式开始之前,先设定父元素,与子元素
<div class="parent">
<div class="son1">1</div>
<div class="son2">2</div>
<div class="son3">3</div>
<div class="son4">4</div>
<div class="son5">5</div>
<div class="son6">6</div>
<div class="son7">7</div>
</div>
.parent{
width: 300px;
height: 300px;
display: flex;
}
.son{
width:50px;
height:50px;
}
//因为子元素都是相同的,为了更加关注于flex布局,笔者这里只写了尺寸,和flex相关属性。
flex-wrap(设置是否换行)
nowrap(默认值) | wrap | wrap-reverse
nowrap
.parent{
width: 300px;
height: 300px;
display: flex;
flex-wrap:nowrap;
}
子元素宽度未溢出
我们可以看到此时子元素宽度为50px
子元素宽度溢出
此时发现,我们有7个子元素,每个子元素为50px,50px*7 >300px,但是子元素并未溢出,此时子元素平分父元素宽度,子元素宽度为300px/7=42.86
wrap
.parent{
width: 300px;
height: 300px;
display: flex;
flex-wrap:wrap;
}
可以看到此时,虽然子元素溢出,但是已经换行
wrap-reverse
.parent{
width: 300px;
height: 300px;
display: flex;
flex-wrap:wrap-reverse;
}
flex-direction(设置主轴方向)
row(默认) | row-reverse | column | column-reverse
主轴的方向决定了交叉轴的方向,前面我们先讲了换行方式,因为交叉轴需要配合多行才能更好的显示效果
row
.parent{
width: 300px;
height: 300px;
display: flex;
flex:wrap;
flex-direction:row;
}
row-reverse
.parent{
width: 300px;
height: 300px;
display: flex;
flex:wrap;
flex-direction:row-reverse;
}
column
.parent{
width: 300px;
height: 300px;
display: flex;
flex:wrap;
flex-direction:column;
}
column-reverse
.parent{
width: 300px;
height: 300px;
display: flex;
flex:wrap;
flex-direction:column-reverse;
}
总结,当主轴为横向时,交叉轴向下,主轴为纵向时,交叉轴向右
flex-flow
flex-dirextion | flex-wrap
flex-flow其实是flex-direction和flex-wrap两个属性的集合,并且没有顺序
一个值
当flex-flow为一个属性时。
.parent{
width: 300px;
height: 300px;
display: flex;
flex-flow: wrap; //此时为flex-wrap的值
}
.parent{
width: 300px;
height: 300px;
display: flex;
flex-flow: row-reverse; //此时为flex-direction的值
}
可以看到此时和单独设置flex-wrap或者flex-direction一样
两个值
既然是flex-direction和flex-wrap两个属性的集合,接下来我们看一看两个值的情况
.parent{
width: 300px;
height: 300px;
display: flex;
flex-flow: row-reverse wrap; //flex-direction | flex-wrap
}
此时我们先写了flex-direction的值,再写的flex-wrap的值,我们将其交换一下试一试:
.parent{
width: 300px;
height: 300px;
display: flex;
flex-flow: wrap; row-reverse//flex-wrap | flex-direction
}
可以发现,此时布局没有任何变化,也就是说,无论先写的是flex-direction的值还是flex-wrap的值都是可以的,并没有像margin一样严格规定了每个值的顺序
justify-content(设置子元素主轴方向上的排列方式)
flex-start | flex-end | center | space-around(两边占中间一半) | space-between(两边相切)
flex-start
.parent{
width: 300px;
height: 300px;
display: flex;
justify-content: flex-start;
}
flex-end
.parent{
width: 300px;
height: 300px;
display: flex;
justify-content: flex-end;
}
center
.parent{
width: 300px;
height: 300px;
display: flex;
justify-content: center;
}
space-around
.parent{
width: 300px;
height: 300px;
display: flex;
justify-content: space-around;
}
此时,你一定很好奇,两边并不是相切的,而且明显比中间短,那么两边的间距到底是多少呢,此时两边的间距为中间间距的一半
space-between
.parent{
width: 300px;
height: 300px;
display: flex;
justify-content: space-between;
}
align-items(设置子元素在交叉轴上的排列方式)
stretch(默认) | flex-start | flex-end | center | baseline
stretch
将子元素在交叉轴上拉伸至父元素一致
子元素在交叉轴上设置了值时
本来准备写宽度,但突然发现好像不是很严谨,故变成了交叉轴有值 我们先来看看此时的父子元素分别是
.parent{
width: 300px;
height: 300px;
display: flex;
align-items: stretch;
}
.son{
width:50px;
height:50px;
}
这时我们发现,当子元素在交叉轴设置了值时,align-items: stretch 失效了。
接下来我们看一看当子元素在交叉轴没有值时
子元素在交叉轴没有设置值时
.parent{
width: 300px;
height: 300px;
display: flex;
align-items: stretch;
}
.son1{
width:50px;
}//注意,这里我只设置了第一个子元素没有高度
这个时候我们发现 align-items: stretch 已经起作用了
flex-start
flex-end
center
baseline
align-content(设置多行子元素在交叉轴上的排列方式)
flex-start | flex-end | center | space-around | space-between | stretch
多行子元素设置在交叉轴的排列方式
我们先来看一看当多行子元素在交叉轴上使用align-items
.parent{
width: 300px;
height: 300px;
display: flex;
flex-wrap: wrap;
align-items: center;
}
可以发现此时设置的align-items: center好像并没有达到我们想要的效果,此时我们就需要align-content属性
flex-start
.parent{
width: 300px;
height: 300px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
flex-end
center
space-around
space-between
stretch
当子元素在交叉轴上有值时,我们发现没有作用
.parent{
width: 300px;
height: 300px;
display: flex;
align-content: stretch;
}
.son{
width:50px;
height:50px;
}
当去掉子元素在交叉轴上的值时
.son1{
width:50px;//注意:此时我们只是去掉了第一个子元素的值
}
子容器
.parent{
width: 300px;
height: 300px;
display: flex;
}
.son{
width:50px;
height:50px;
}
align-self(设置单个子元素在交叉轴上的排列方式)
auto(默认值) | stretch | flex-start | flex-end | center | baseline
auto
自动继承父元素的align-items属性
stretch
同样,如果子元素在交叉轴上设置了数值,便不起作用
.son{
width:50px;
height:50px;
align-self: stretch;
}
当子元素未设值时
.son1{
width:50px;
align-self: stretch;
}
flex-start
flex-end
center
baseline
.son2{
width:50px;
height:50px;
align-self: baseline;
}
order
子元素的排列顺序,越小越靠前,默认值为0,可以接受负值
.son2{
order:-5;
}
.son3{
order:-4;
}
flex-grow(子元素拉伸因子)
在学习flex-grow之前,我们先要弄懂一个概念:剩余空间
父元素-所有子元素 = 剩余空间
在此例中,我们的剩余空间为:300px - 50px*3 = 150px
当我们设置每个元素的拉伸比例
.son1{
flex-grow:1;
}
.son2{
flex-grow:2;
}
.son3{
flex-grow:3;
}
子元素1:50px + 1/(1+2+3)*150px = 75px
子元素2:50px + 2/(1+2+3)*150px = 100px
子元素3:50px + 3/(1+2+3)*150px = 125px
当然,flex-grow设置为负数和百分比,或者带单位的数字是不起作用的
当flex-grow设置为小数时,将会把剩余空间设置为1
.son1{
flex-grow: 0.2;
}
子元素1: 50px + 0.2/1*150px = 80px
flex-shrink(子元素收缩规则)
当子元素的总空间大于父元素的空间时,剩余空间将转化为溢出空间
.son1{
width: 150px;
}
.son1{
width: 150px;
}
.son1{
width: 150px;
}
当我们把子元素都设置为150px,子元素总空间:150px*3 = 450px ,是大于父元素空间300px的
当然,之前我们看过当子元素总空间大于父元素时,实际宽度为平分父元素空间
当我们设置子元素
.son1{
width: 150px;
flex-shrink: 1;
}
.son1{
width: 150px;
flex-shrink: 2;
}
.son1{
width: 150px;
flex-shrink: 3;
}
此时: 子元素1:150px- (150px* 1/150px* 1+150px* 2+150px* 3)*150px = 125px
子元素2:150px- (150px* 2/150px* 1+150px* 2+150px* 3)*150px = 100px
子元素3:150px- (150px * 3/150px * 1+150px * 2+150px* 3)*150px = 75px
flex-basis(子元素主轴方向的基础大小)
优先级:flex-basis > width
.son1{
width: 50px;
flex-basis: 100px;
}
我们发现此时的子元素宽度变为100px,可接受参数为带单位的数值和百分比
flex
为flex-grow,flex-shrink,flex-basis三个属性的集合
/* 单值,无单位数字:flex:<flex-grow> 1 0
flex: 2;
/* 单值,宽度/高度:flex: 1 1 <flex-basis> */
flex: 10em;
flex: 30px;
flex: min-content;
/* 双值:flex:<flex-grow> 1 <flex-basis> */
flex: 1 30px;
/* 双值:flex: <flex-grow> <flex-shrink> 0*/
flex: 2 2;
/* 三值:flex:<flex-grow> <flex-shrink> <flex-basis>*/
flex: 2 2 10%;
一道经典面试题
面试官,了解flex:1吗?请解释一下
答:首先是flex为flex-grow和flex-shrink和flex-basis的缩写,当flex的值为不带单位的单值时候
flex三个属性分别为:
flex-grow:1
flex-shrink:1
flex-basis:0
结语
希望看完此篇flex布局,能对你有所帮助,感谢观看,如有错误,还望指正
感谢
深入理解 flex-grow、flex-shrink、flex-basis(如果还对子元素的flex简写属性有疑惑,强烈建议观看这篇文章)