css中的flex布局
当在父元素设置属性为flex后,即使不设置父元素的属性也会自带align-content:stretch
、align-items:stretch
、flex-wrap:nowrap
。如果不做更改,默认情况下子元素显示单行效果且高度为父元素的高度。
flex-grow
在每一行上根据设置的值来平均分配剩余的空间。
假设父元素宽度为300px,一个子元素为50px,一个为100px,则当我们分别给两个元素设置flex-grow后,我们其实是对父元素减去两个子元素的宽度后的长度进行分配。如果两个子元素都设置了1的话,即50变为50 + (300 - 50 - 100)/2,100变为100 + (300 - 50 - 100)/2。
flex-shrink
设置元素的缩放比例,当子元素的宽度和大于父元素的宽度后,按照设置的这个比列缩放每一个子元素。根据设置的flex-shrink计算每一个子元素的缩放比列。如
.flex{display:flex;}
.flex div{height:100px;}
.w1{width:400px;}
.w2{width:100px;}
.w3{width:200px;}
.w4{width:300px;}
...
<div class="flex w1">
<div class="w2"></div>
<div class="w3"></div>
<div class="w4"></div>
</div>
由于flex-shrink的默认值为1。根据这个值计算每一个子元素的缩放比例。
子元素的宽度比例为: 1 : 2 : 3
flex-shrink设置的比例:1 : 1 : 1
实际需要缩小的比重:1 * 1 : 2 * 1 : 3 * 1
按照比例计算每一个子元素需要减少的宽度为:200 * 1 / 6,200 * 2 / 6, 200 * 3 / 6
如果将w4的flex-shrink设置为2。计算新的缩小比重为: 1 * 1 : 2 * 1 : 3 * 2
再按照新的比例计算每一个元素需要减少的宽度: 200 * 1 / 9, 200 * 2 / 9, 200 * 6 / 9
flex-basis
设置子元素的初始宽度或高度。优先级高于宽度和高度,当设置了flex-basis和width或height后,flex-shrink的计算会按照flex-basis进行计算。
flex-basis.jpg
flex-direction
设置flex的伸缩方向,子元素的排列方向(向上,向下,向左,向右),可以结合flex-grow实现上下自适应布局。
flex-wrap
设置子元素在宽度和大于父元素宽度后是否换行,以及换行后是否反向显示。
align-content
设置多行子元素在纵向上的对齐方式,设置在父元素中,默认值为stretch。
- flex-start:多行元素贴在一起显示在父元素的顶部。
- flex-end: 多行元素贴在一起显示在父元素的底部。
- center: 多行元素贴在一起显示在父元素的中间。
- space-between:如果多行的高度和(一行的高度按照最高的计算)大于等于父元素的高度,则显示flex-start的效果,如果小于的话,首行上边框线贴着父元素的上边框线,最后一行的下边框线贴着父元素的下边框线,然后将多出的高度平分到行间距中。
- space-around:如果多行的高度和(一行的高度按照最高的计算)大于等于父元素的高度,则显示flex-start的效果,如果小于的话,将多出的高度平分到每行的两侧。
- stretch: 如果多行的高度和(一行的高度按照最高的计算)大于等于父元素的高度,则显示flex-start的效果,如果小于的话,根据行数进行平均分配多出的高度。
当设置space-between时
space-between.png
当设置stretch时:
stretch.png
修改height为auto后的图:
stretch1.png
align-content: space-around + align-items: center
的效果等同于align-content: stretch + align-items: center
从上面案例可以知道,stretch会扩大行的高度。但其他的属性对行的高度没有影响,以最高的元素为当前行的高度。
align-items
设置每行中的所有子元素在纵向上的对齐方式,当子元素为多行的时候,先按照多行的分配方式分配界面(高度和宽度)。当多行分配好后,再进行单行子元素的对齐。(不管是多行还是单行,这个属性都会生效,只是它的生效范围发生了变化。)
- felx-start: 同行中的元素贴着前一个元素的后面紧靠父元素的左侧边框线
- flex-end: 同行中的元素贴着后一个元素的后面紧靠父元素的右侧边框线
- center:同行中的元素贴在一起居中在父元素的中间(在一行中水平居中)
- stretch:每行中的元素在纵向上铺满该行。
该属性只对当前行的子元素有影响,对其他行的子元素不会有任何影响。
align-self
设置元素自身在当前行的纵向上的对齐方式(即父元素中的单个子元素)
- flex-start:自身元素与当前行的顶部对齐。
- flex-end:自身元素与当前行的底部对齐。
- center: 自身元素在当前行显示居中效果。
- stretch: 当设置自身元素的高度为auto或不设置高度时,元素会根据元素纵向上占用所剩余的空间。如果子元素为单行的话,该元素会占用整个父元素的高度。如果子元素为多行的话,则每行子元素会先根据align-content中的stretch来分配高度,再根据元素自身的对齐方式来分配元素在该行上的占用位置或高度。
justify-content
设置单行子元素在横向上的对齐方式,如果子元素被分为多行的话,该属性用于设置在每行中的子元素的对齐方式。
- flex-start:该行元素左对齐
- flex-end:该行元素右对齐
- center:该行元素居中对齐
- space-between:如果该行元素大于两个的话,第一个元素的左侧边框线和父元素的左侧边框线重合,最后一个元素的右侧边框和父元素的右边框线重合,最后将剩余的空间平均分配到行间距中(行与行之间的距离)。
- space-around: 将剩余的空间平均分配到每一个行的两边。
父元素的平均分配给两个子元素
当两个子元素都有内容的时候直接使用flex-grow: 1
并不能实现两个子元素等宽,需要设置两个子元素宽度相等且宽度和不超过父元素才可以实现子元素的等宽。由于flex-grow
是用来分配剩余空间的,所以只要设置width: 0;flex-grow: 1;
就可以实现子元素的宽度相等。
<div style="display: flex;height:100px;">
<div style="width: 0;flex-grow: 1;background:#d8d8d8;"></div>
<div style="width: 0;flex-grow: 1;background:#333;"></div>
</div>
pingjun.png
当我们在子元素中设置不同长度的文本,在去掉
width: 0;
后,布局变得不再平分:pingf2.png
实现上下和左右的自适应布局
在弹性布局出现之前,我们采用浮动和定位的方式实现页面的自适应,从弹性布局出现后,自适应布局变得简单。
左右布局(对于需要自适应的模块设置flex-grow)
.flex{display: flex;}
.bg1{background: #e8e8e8;}
.bg2{background: #bfb9bf;}
.w2{width: 100px;}
.flex-1{flex-grow: 1;}
...
<div class="flex w1">
<div class="w2 bg1"></div>
<div class="flex-1 bg2"></div>
</div>
上下布局
.flex-dir{flex-direction: column;}
.flex{display: flex;}
.bg1{background: #e8e8e8;}
.bg2{background: #bfb9bf;}
.w2{width: 100px;}
.flex-1{flex-grow: 1;}
...
<div class="flex w1 flex-dir">
<div class="w2 bg1"></div>
<div class="flex-1 bg2"></div>
</div>