css 的 flex 弹性布局在平常开发中有着普遍的应用,其弹性伸缩的灵活性对响应式需求的开发提供了便利,栅格布局,垂直居中等等设置flex布局后,加上几个属性就能够轻松实现。基本使用能够参考阮老师的博客css
flex能够当作一个容器,其中有一个主轴(main axis)和交叉轴(cross axis)做为容器内容的排布基准。容器中的每一个子元素称为项目,这些项目都排列在主轴(main axis)上,每一个项目在主轴方向上占用空间称为main size。咱们能够经过设置项目的width属性来指定main size的大小,也能够经过flex属性(flex-grow,flex-strink,flex-basic的结合)使main size大小成为响应式。html
每一个项目上直接设置width大小,项目大小即为width的值,这种方式不会让宽度自适应,若是容器宽度大于或小于项目宽度总和,就会出现容器有大量留白或超出容器的状况,为了不这种状况,一般会指定flex属性来使项目宽度自适应从而占满整个容器。算法
指定flex-grow属性,项目会自动扩张到和容器宽度一致布局
计算相加每一个项目flex-grow得出总和为T,并将容器宽度W均分红W/T,每一个项目的宽度就是flex
main size = flex-grow * W / Tspa
演示地址3d
容器宽度先减去这些项目width或flex-basic的值,容器剩下的宽度会按flex-grow来计算并分配给全部项目。main size = flex-basic + (W - 每一个项目宽度) * flex-grow / Tcode
*注:flex-basic的优先级高于widthhtm
演示地址blog
项目宽度先按上面两个算法计算出宽度,若是项目宽度大于了max-width,多余的宽度会从新分配给没有设置max-width属性的项目。
计算法则
指定flex-strink属性,项目宽度会自动收缩到和容器宽度一致。引用MND上的说法:
CSS flex-shrink 属性指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值
其实这里收缩和扩张的算法是不同的,收缩的大小不能直接用flex-strink来计算,以这段代码为例:
.flex-item1 { background-color: red; flex: 0 8 800px; } .flex-item2 { background-color: gray; flex: 0 4 400px; } .flex-item3 { background-color: antiquewhite; flex: 0 2 200px; } .flex-item4 { background-color: orange; flex: 0 1 100px; }
这里能够计算出项目的总宽度是 1500px 大于了容器宽度 1000px,按照MDN的说法,计算第一个项目的宽度应该是:800 - (1500 - 1000)*(8 / 15)= 533.33px
能够看出项目的收缩大小并非经过flex-strink直接获得的,要计算项目的收缩后的宽度,还须要用到flex-basic。以上面的代码为例,先要去计算项目的虚拟总宽度VS = 各项目flex-basic flex-strink 之和,再计算单个项目的占比P = flex flex-strink / VS,最后计算项目应该减去的大小 = 真实超出部分 * P,
能够计算出第一个项目的宽度为:
先计算出项目收缩后的宽度,若是项目宽度大于了max-width,最终项目的大小会以max-width的值为准,且多余的宽度会分配给其余项目;若是项目小于了min-width,最终项目的大小会以min-width为准,且少分配的宽度会从其余项目中减去。分配给其余项目的这部分宽度要准守上面所写的计算规则按占比分配
先计算出项目收缩后的宽度,按照“多退少补”的方式来处理max-width和min-width的状况,举个例子:
.flex-item1 { background-color: red; flex: 0 4 400px; /* 240 */ min-width: 310px; } .flex-item2 { background-color: gray; flex: 0 2 400px; /* 320 */ max-width: 280px; } .flex-item3 { background-color: antiquewhite; flex: 0 4 200px; /* 120 */ max-width: 100px; } .flex-item4 { background-color: orange; flex: 0 2 200px; /* 160 */ } .flex-item5 { background-color: lightcoral; flex: 0 2 200px; /* 160 */ }
项目1收缩后的宽度是240px,min-width是300px,因此项目1就借走了60px须要从其余项目中补上60px;项目2收缩后的宽度是320px,max-width是280px,因此项目2少了40px就退给其余项目;项目3页同理,120-100=20px,要退给其余项目20px。来来回回发现,就这项目1借的宽度恰好能够由项目2和项目3补上,互补以后两清了,因而,项目4和项目5的宽度不受影响不变化。
项目的宽度超出了容器的宽度,超出部分的项目自动移动到到下一行去,在每一行中,项目的宽度计算都以flex-grow为准
若是position的值使项目脱离文档流,容器中的项目flex属性就会失效,其余的项目宽度按flex属性自适应。
flex布局中项目的自适应宽度(高度)经过flex-grow和flex-strink决定的,两者都是将容器中剩余或超出的宽度(高度)分配给各个项目,flex-grow是将剩余宽度按flex-grow比分配给各个项目,flex-strink是根据各个项目本来宽度*flex-strink占总虚拟宽度的比来分配项目应该减去的宽度。