Flex布局 | 青训营笔记

147 阅读8分钟

这是我参与「第四届青训营 -前端场」笔记创作活动的的第2篇笔记

Flex布局

布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现

介绍

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为flex布局.

  • 当我们为父盒子设为flex布局后,子元素的float,clear,和vectical-align将会失效

给父亲使用,成为容器,孩子叫做项目. 说直白点就是给父盒子添加flex属性,来控制子盒子的位置和排列方式.

给div这类块状元素元素设置display:flex或者给span这类内联元素设置display:inline-flex,flex布局即创建!

flex和inline-flex区别在于,inline-flex容器为inline特性,因此可以和图片文字一行显示;flex容器保持块状特性,宽度默认100%,不和内联元素一行显示。

作用在flex容器上作用在flex子项上
flex-direction 设置主轴方向order
flex-wrap 子元素是否换行flex-grow
flex-flow 相当于设置主轴方向和是否换行flex-shrink
justify-content 设置主轴排列方式flex-basis
align-items 设置侧轴排列方式 单行flex
align-content 设置侧轴排列方式 多行align-self

父属性

设置主轴方向

image.png 上图是默认的主轴和侧轴,这些是可以变换的

 flex-direction: row | row-reverse | column | column-reverse;
  • row

    • 默认值,显示为行。方向为当前文档水平流方向,默认情况下是从左往右。如果当前水平文档流方向是rtl(如设置direction:rtl),则从右往左。
  • row-reverse

    • 显示为行。但方向和row属性值是反的。
  • column

    • 显示为列。
  • column-reverse

    • 显示为列。但方向和column属性值是反的。

设置主轴上的子元素排列方式

 justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
  • flex-start

    • 默认值。逻辑CSS属性值,与文档流方向相关。默认表现为左对齐。
  • flex-end

    • 逻辑CSS属性值,与文档流方向相关。默认表现为右对齐。
  • center

    • 表现为居中对齐。
  • space-between

    • 表现为两端对齐。between是中间的意思,意思是多余的空白间距只在元素中间区域分配。使用抽象图形示意如下:
    • image.png
  • space-around

    • around是环绕的意思,意思是每个flex子项两侧都环绕互不干扰的等宽的空白间距,最终视觉上边缘两侧的空白只有中间空白宽度一半。使用抽象图形示意如下:
    • image.png
  • space-evenly

    • evenly是匀称、平等的意思。也就是视觉上,每个flex子项两侧空白间距完全相等。使用抽象图形示意如下:
    • image.png

设置子标签是否换行

默认是不换行的,装不下会缩小子元素的宽度

 flex-wrap: nowrap | wrap | wrap-reverse;

设置测轴的子元素排列方式

align-items中的items指的就是flex子项们,因此align-items指的就是flex子项们相对于flex容器在垂直方向上的对齐方式,大家是一起顶部对齐呢,底部对齐呢,还是拉伸对齐呢,类似这样。

语法如下:

 align-items: stretch | flex-start | flex-end | center | baseline;

其中:

  • stretch

    默认值。flex子项拉伸。如果flex子项设置了高度,则按照设置的高度值渲染,而非拉伸。

  • flex-start

    逻辑CSS属性值,与文档流方向相关。默认表现为容器顶部对齐。

  • flex-end

    逻辑CSS属性值,与文档流方向相关。默认表现为容器底部对齐。

  • center

    表现为垂直居中对齐。

  • baseline

    表现为所有flex子项都相对于flex容器的基线(字母x的下边缘)对齐。

align-content

align-content可以看成和justify-content是相似且对立的属性,justify-content指明水平方向flex子项的对齐和分布方式,而align-content则是指明垂直方向每一行flex元素的对齐和分布方式。如果所有flex子项只有一行,则align-content属性是没有任何效果的。

语法如下:

 align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;

其中:

  • stretch

    默认值。每一行flex子元素都等比例拉伸。例如,如果共两行flex子元素,则每一行拉伸高度是50%。

  • flex-start

    逻辑CSS属性值,与文档流方向相关。默认表现为顶部堆砌。

  • flex-end

    逻辑CSS属性值,与文档流方向相关。默认表现为底部堆放。

  • center

    表现为整体垂直居中对齐。

  • space-between

    表现为上下两行两端对齐。剩下每一行元素等分剩余空间。

  • space-around

    每一行元素上下都享有独立不重叠的空白空间。

  • space-evenly

    每一行元素都完全上下等分。

复合属性

flex-flow属性是flex-directionflex-wrap的缩写,表示flex布局的flow流动特性,语法如下:

 flex-flow: <‘flex-direction’> || <‘flex-wrap’>

当多属性同时使用的时候,使用空格分隔。

举个例子,容器元素如下设置:

 .container {
     display: flex;
     flex-flow: row-reverse wrap-reverse;
 }

子属性

flex属性

flex属性是flex-growflex-shrinkflex-basis的缩写。

其中第2和第3个参数(flex-shrinkflex-basis)是可选的。默认值为0 1 auto

flex-grow

flex-grow属性中的grow是扩展的意思,扩展的就是flex子项所占据的宽度,扩展所侵占的空间就是除去元素外的剩余的空白间隙。

具体的扩展比较复杂。在展开之前,我们先看下语法。

语法:

 flex-grow: <number>; /* 数值,可以是小数,默认值是 0 */

flex-grow不支持负值,默认值是0,表示不占用剩余的空白间隙扩展自己的宽度。如果flex-grow大于0,则flex容器剩余空间的分配就会发生,具体规则如下:

  • 所有剩余空间总量是1。

  • 如果只有一个flex子项设置了

     flex-grow
    

    属性值:

    • 如果flex-grow值小于1,则扩展的空间就总剩余空间和这个比例的计算值。
    • 如果flex-grow值大于1,则独享所有剩余空间。
  • 如果有多个flex设置了

     flex-grow
    

    属性值:

    • 如果flex-grow值总和小于1,则每个子项扩展的空间就总剩余空间和当前元素设置的flex-grow比例的计算值。
    • 如果flex-grow值总和大于1,则所有剩余空间被利用,分配比例就是flex-grow属性值的比例。例如所有的flex子项都设置flex-grow:1,则表示剩余空白间隙大家等分,如果设置的flex-grow比例是1:2:1,则中间的flex子项占据一半的空白间隙,剩下的前后两个元素等分。

flex-shrink

shrink是“收缩”的意思,flex-shrink主要处理当flex容器空间不足时候,单个元素的收缩比例。

语法如下:

 flex-shrink: <number>; /* 数值,默认值是 1 */

flex-shrink不支持负值,默认值是1,也就是默认所有的flex子项都会收缩。如果设置为0,则表示不收缩,保持原始的fit-content宽度。

flex-shrink的内核跟flex-grow很神似,flex-grow是空间足够时候如何利用空间,flex-shrink则是空间不足时候如何收缩腾出空间。总有点CP的味道。

两者的规则也是类似。已知flex子项不换行,且容器空间不足,不足的空间就是“完全收缩的尺寸”:

  • 如果只有一个flex子项设置了

     flex-shrink
    
    • flex-shrink值小于1,则收缩的尺寸不完全,会有一部分内容溢出flex容器。
    • flex-shrink值大于等于1,则收缩完全,正好填满flex容器。
  • 如果多个flex子项设置了

     flex-shrink
    
    • flex-shrink值的总和小于1,则收缩的尺寸不完全,每个元素收缩尺寸占“完全收缩的尺寸”的比例就是设置的flex-shrink的值。
    • flex-shrink值的总和大于1,则收缩完全,每个元素收缩尺寸的比例和flex-shrink值的比例一样。下面案例演示的就是此场景。

flex-basis

flex-basis定义了在分配剩余空间之前元素的默认大小。相当于对浏览器提前告知:浏览器兄,我要占据这么大的空间,提前帮我预留好。

语法如下:

 flex-basis: <length> | auto; /* 默认值是 auto */

默认值是auto,就是自动。有设置width则占据空间就是width,没有设置就按内容宽度来。

如果同时设置widthflex-basis,就渲染表现来看,会忽略width。flex顾名思义就是弹性的意思,因此,实际上不建议对flex子项使用width属性,因为不够弹性。

当剩余空间不足的时候,flex子项的实际宽度并通常不是设置的flex-basis尺寸,因为flex布局剩余空间不足的时候默认会收缩。

align-self控制子项自己在侧轴上的排列方式

align-self指控制单独某一个flex子项的垂直对齐方式,写在flex容器上的这个align-items属性,后面是items,有个s,表示子项们,是全体;这里是self,单独一个个体。其他区别不大,语法几乎一样:

 align-self: auto | flex-start | flex-end | center | baseline | stretch;

image.png

order定义排列顺序

我们可以通过设置order改变某一个flex子项的排序位置。

语法:

 order: <integer>; /* 整数值,默认值是 0 */

所有flex子项的默认order属性值是0,因此,如果我们想要某一个flex子项在最前面显示,可以设置比0小的整数,如-1就可以了。