鲁迅有云: 搬砖的一天从flex布局开始。
一: flex布局的用法
flex布局不同于传统的盒子模型,它通过元素在主轴和副轴上的排列方式,来确定元素的位置。
通过display: flex 就可以设置flex布局。
flex布局默认有两条轴线。main axis / cross axis
水平的是主轴(main axis) 垂直的副轴(cross axis)
主轴开始的位置是main start 结束位置是main end 副轴开始的位置是cross start 结束位置cross end
二: flex布局属性
1. flex-direction: 属性决定main axis 的方向。就是元素如何在主轴上排列的。
flex-direction: row : 主轴为水平方向,从左到右。
flex-direction: row-reverse: 相反。
flex-direction: column: 主轴为垂直方向,起点在上沿。
flex-direction: colum-reverse: 相反
2. flex-wrap:属性决定在轴线上如何排列。
wrap: 主轴换行,在下一列换行。
nowrap: 不换行(默认值)
wrap-reverse: 上一行换行。
3.justify-content
该属性定义在主轴上的排列方式。
justify-content: center
justify-content: flex-start
justify-content: flex-end
justify-content: space-betwteen
justify-content: space-around
主要注意的是:space-between和space-around的区别。
space-between是两端对齐,子元素的间隔相等。
space-around是每个子元素两侧的间距都相等,所有子元素之间的间隔是元素于边框之间间隔的一倍。
4.align-items
align-items定义元素在副轴上的排列方式。
1. flex-end: 终点对齐
2. flex-start: 起点对齐
3. center:居中
4. stretch: 如果项目未设置高度或设为auto,将占满整个容器的高度。
5. baseline: 基准线,项目的第一行文字的基线对齐。
三: flex布局元素的属性
1. 剩余空间于不足空间
在Flexbox布局中,Flex容器中包含一个或多个Flex项目(该容器的子元素或子节点)。Flex容器和Flex项目都有其自身的尺寸大小,那么就会有:Flex项目尺寸大小之和大于或小于Flex容器 情景:
- 当所有Flex项目尺寸大小之和小于Flex容器时,Flex容器就会有多余的空间没有被填充,那么这个空间就被称为Flex容器的剩余空间(Positive Free Space)
- 当所有Flex项目尺寸大小之和大于Flex容器时,Flex容器就没有足够的空间容纳所有Flex项目,那么多出来的这个空间就被称为负空间(Negative Free Space)
2.flex 项目的计算问题
在Flexbox布局当中,其中 flex-grow、flex-shrink和flex-basis都将会影响Flex项目的计算。
1.flex-basis属性
在浏览器初始化的时候定义好flex元素的宽度的属性。默认值为auto。浏览器会先解析你是否给元素设置宽度,假如你设置了width: 200px ; 那么flex-basis的值就为200px。
如果你的flex项目没有设置宽度,并且flex-basis默认值为auto,那么浏览器会解析内部的content来确定flex项目的大小。
item1的width为500px;虽然设置的width,但是还是以flex-basis的值为准。
item2 没有设置width,默认flex-basis为width。
item3 flex-basis:auto, 会解析内部的content,以内部content为准。
简单总结一下:
flex-basis默认值为auto- 如果Flex项目显式的设置了
width值,同时flex-basis为auto时,则Flex项目的宽度为按width来计算,如果未显式设置width,则按Flex项目的内容宽度来计算 - 如果Flex项目显式的设置了
width值,同时显式设置了flex-basis的具体值,则Flex项目会忽略width值,会按flex-basis来计算Flex项目 - 当Flex容器剩余空间不足时,Flex项目的实际宽度并不会按
flex-basis来计算,会根据flex-grow和flex-shrink设置的值给Flex项目分配相应的空间 - 对于Flexbox布局中,不建议显式的设置Flex项目的
width值,而是通过flex-basis来控制Flex项目的宽度,这样更具弹性 - 如果Flex项目显式的设置了
min-width或max-width值时,当flex-basis计算出来的值小于min-width则按min-width值设置Flex项目宽度,反之,计算出来的值大于max-width值时,则按max-width的值设置Flex项目宽度。
2. flex-grow: flex的扩大因子
当Flex容器有一定的剩余空间时,flex-grow可以让Flex项目分配Flex容器剩余的空间,每个Flex项目将根据flex-grow因子扩展,从而让Flex项目布满整个Flex容器(有效利用Flex容器的剩余空间)。flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
- 所有Flex项目设置相同的
flex-grow值 - 每个Flex项目设置不同的
flex-grow值
情形1: flex-grow相等 并且 flex-grow的值都大于等于1
初始值: item1 == item2 == item3 == item4 == 200
flex-grow:item1 == item2 == item3 == item4 == 1
现在值:item1 == item2 == item3 == item4 == 316
总宽度为1264: 剩余容器: 1264 - 4 * 200 = 464
flex-grow的总和为4: 每个元素的分配比例ratios为 flex-grow(单个)/ flex-grow(总数) == 1/4;
现在宽度为: widthNow = widthBefore + 464 * ratios = 200 + 116 = 316;
情形2: flex-grow设置为1 / 2 /3 /4(flex-grow: 不相等)
把Flex项目的
分别设置为1:2:3:4。也就是说把Flex容器的剩余空间分成了10份(1 + 2 + 3 + 4 = 10),而每个Flex项目分别占用Flex容器剩余空间的1/10、2/10、3/10和4/10。就上例而言,Flex容器剩余空间是180px,按这样的计算可以得知,每一份的长度是180px / 10 = 18px,如此一来,每个Flex项目的宽度则变成:
- flex1 : 200px + 18px = 218px;
- flex2: 200px + 18px * 2 = 236px;
- flex3: 200px + 18px * 3 = 254px;
- flex4: 200px + 18px * 4 = 272px;
情形3: flex设置为小数并且所有flex-grow的值之和小于1
flex-grow的值也可以设为小于1的值。其实都是一样的计算,唯一不同的是,如果所有flex-grow的值之和小于1,说明子元素没有把容器分配完,还有剩余的容器大小。
计算:
剩余容器: screenWidth - itemWidth * 4 = 1264 - 800 = 464;
剩余使用容器(OvcWidth) = 464 * .8 = 371.2;
item容器:itemWidth = 200 + 371.2 * 1/4 = 292;
2.flex-shrink属性
flex-shrink和flex-grow类似,只不过flex-shrink是用来控制Flex项目缩放因子。当所有Flex项目宽度之和大于Flex容器时,将会溢出容器(flex-wrap为nowrap时),flex-shrink就可以根据Flex项目设置的数值比例来分配Flex容器的不足空间,也就是按比例因子缩小自身的宽度,以免溢出Flex容器。flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
flex-shrink接收一个<number>值,其默认值为1。也就是说,只要容器宽度不足够容纳所有Flex项目时,所有Flex项目默认都会收缩。如果你不想让Flex项目进行收缩时,可以设置其值为0,此时Flex项目始终会保持原始的fit-content宽度。同样的,flex-shrink也不接受一个负值做为属性值。
情形1: flex-shrink 相等并且大于等于1
计算类似于flex-grow: 元素的宽度减去分配的缩小宽度
shrinkWidth === (400 * 4 - 1264) * 1/4 = 84;
width = 400 - 84 = 316px;
情形2: flex-shrink 不想等
shrinkWidthRatio(缩小分配比例) === (400 * 4 - 1264) * 1/10;
item1 = width - shrinkWidthRatio * 1 = 366
item2 = width - shrinkWidthRatio * 2 = 332
item3 = width - shrinkWidthRatio * 3 = 299
item4 = width - shrinkWidthRatio * 4 = 256
情形3:flex-shrink也可以设置一个小于1的值,比如我们给所有的Flex项目设置flex-shrink的值为0.2.当所有Flex项目的收缩因子(flex-shrink)总和小于1时,Flex容器不足空间不会完全分配完,依旧会溢出Flex容器。
总结一下:
大部分情形之下,我们都是使用flex属性来设置Flex项目的伸缩的值。其常见值的效果有:
flex: 0 auto和flex:initial,这两个值与flex: 0 1 auto相同,也是初始值。会根据width属性决定Flex项目的尺寸。当Flex容器有剩余空间时,Flex项目无法扩展;当Flex容器有不足空间时,Flex项目收缩到其最小值min-content。flex: auto与flex: 1 1 auto相同。Flex项目会根据width来决定大小,但是完全可以扩展Flex容器剩余的空间。如果所有Flex项目均为flex: auto、flex:initial或flex: none,则Flex项目尺寸决定后,Flex容器剩余空间会被平均分给是flex:a uto的Flex项目。flex: none与flex: 0 0 auto相同。Flex项目根据width决定大小,但是完全不可伸缩,其效果和initial类似,这种情况下,即使在Flex容器空间不够而溢出的情况之下,Flex项目也不会收缩。flex: <positive-number>(正数)与flex: 1 0px相同。该值使Flex项目可伸缩,并将flex-basis值设置为0,导致Flex项目会根据设置的比例因子来计算Flex容器的剩余空间。如果所有Flex项目都使用该模式,则它们的尺寸会正比于指定的伸缩比。