从flex布局到flex演算法~~

344 阅读8分钟

鲁迅有云: 搬砖的一天从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-growflex-shrinkflex-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-basisauto时,则Flex项目的宽度为按width来计算,如果未显式设置width,则按Flex项目的内容宽度来计算
  • 如果Flex项目显式的设置了width值,同时显式设置了flex-basis的具体值,则Flex项目会忽略width值,会按flex-basis来计算Flex项目
  • 当Flex容器剩余空间不足时,Flex项目的实际宽度并不会按flex-basis来计算,会根据flex-growflex-shrink设置的值给Flex项目分配相应的空间
  • 对于Flexbox布局中,不建议显式的设置Flex项目的width值,而是通过flex-basis来控制Flex项目的宽度,这样更具弹性
  • 如果Flex项目显式的设置了min-widthmax-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项目的

flex-grow 

分别设置为1:2:3:4。也就是说把Flex容器的剩余空间分成了10份(1 + 2 + 3 + 4 = 10),而每个Flex项目分别占用Flex容器剩余空间的1/102/103/104/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-shrinkflex-grow类似,只不过flex-shrink是用来控制Flex项目缩放因子。当所有Flex项目宽度之和大于Flex容器时,将会溢出容器(flex-wrapnowrap时),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 autoflex:initial,这两个值与flex: 0 1 auto相同,也是初始值。会根据width属性决定Flex项目的尺寸。当Flex容器有剩余空间时,Flex项目无法扩展;当Flex容器有不足空间时,Flex项目收缩到其最小值min-content
  • flex: autoflex: 1 1 auto相同。Flex项目会根据width来决定大小,但是完全可以扩展Flex容器剩余的空间。如果所有Flex项目均为flex: autoflex:initialflex: none,则Flex项目尺寸决定后,Flex容器剩余空间会被平均分给是flex:a uto的Flex项目。
  • flex: noneflex: 0 0 auto相同。Flex项目根据width决定大小,但是完全不可伸缩,其效果和initial类似,这种情况下,即使在Flex容器空间不够而溢出的情况之下,Flex项目也不会收缩。
  • flex: <positive-number>(正数)与flex: 1 0px相同。该值使Flex项目可伸缩,并将flex-basis值设置为0,导致Flex项目会根据设置的比例因子来计算Flex容器的剩余空间。如果所有Flex项目都使用该模式,则它们的尺寸会正比于指定的伸缩比。