阅读 319

一篇文章弄懂flex布局

【关键词】:flex 布局

整理了一张思维导图,放在了文章最后,文字恐惧症可以直接翻到最后查看。

原文链接: 一篇文章弄懂flex布局

0. 前言

  笔者布局时常用float,inline-block,对于flex,仅限于了解,却一直没有应用,遂决定抽出些时间学习一下,初次写难免有漏洞,欢迎指正,后期不定期持续持续更新补充。

  咱们首先从定义入手,flex到底是个什么东西呢?

  flex(flexible box):弹性布局盒子模型,是W3C中新增的属性,在写之前demo练习中,明显感觉到flex,非常的便捷,短短几行代码便可以达到布局的效果,功能也非常的强大,既然吹得这么厉害,俗话说无码无真相,下面我们一起看一下神奇的flex吧!

1. 基础概念

  首先要介绍下flex容器和flex项目,当某个元素采用flex布局时,元素自动转化为Flex容器(flex-container),简称容器。元素内的子元素自动转化为容器内的项目,即Flex项目(flex items),简称项目。

  容器内默认有两轴四点,两轴分别为纵向的主轴(main axis)和垂直主轴的交叉轴(cross axis),两轴分别有各自的起点及中点,主轴起点为main start,主轴的终点为main end,交叉轴的起点称为cross start,终点称为cross end, 项目按照主轴或者交叉轴进行排布,项目沿着主轴方向的尺寸称为main size,项目沿着交叉轴方向的尺寸为cross size,项目默认是按照主轴方向排布的,并且默认不折行,(以主轴排布)当项目宽度总和大于容器宽度时,各个项目宽度压缩,即使设置固定宽度。

image.png

flex布局中项目既可以是行内元素(span)也可以是块级元素(div),项目为行内元素时(见图二),可以对项目进行宽高的设置。此外,需注意使用flex容器内元素,即flex item的float,clear(清浮动)、vertical-align属性将失效,position属性可以正常使用。

2. 容器属性(父属性:Properties for the Parent)

容器属性包含有六个属性:

1. flex-direction
2. flex-wrap
3. flex-flow
4. justify-content
5. align-items
6. align-content
复制代码

  2.1 flex-direction属性

flex-direction属性为项目排列方向,其中包含4个值。

1. row(默认项目排列方向)  //容器主轴为水平方向,其中项目自左向右按顺序依次排布; (left-to-right)
2. row-reverse      //容器主轴仍为水平方向,其中项目自右向左依次排布;(right-to-left)
3. column         //容器主轴为垂直方向,项目自上而下排布;(top-to-bottom)
4. column-reverse     //容器主轴为垂直方向,项目自下而上排布;(bottom-to-top)
复制代码

image.png

四幅图分别对应flex-direction属性的4个值,(demo信息:**容器尺寸为宽500px,高300px,每个项目为直径100px的圆**)图二,图三容器主轴为水平方向演示,当项目总宽度大于容器宽度时项目宽度被压缩,容器主轴为垂直方向时,同理。项目总宽度/高度小于容器时,按照设置宽高沿着主轴排布。

图四,图五不难看出并不符合,我们所说的项目总高度大于容器高度,项目被均匀压缩情况即图二,图三。这是因为我们设置了line-height: 100px,在flex布局中行高的影响并没有被消除,导致项目并没有被压缩在容器中,设置行高后,项目累计高度大于容器部分的内容,在容器之外显示,由于设置了over-flow:hidden;所以在图四图五中,没有显示,仔细看不难发现图四中的三弟圆显示不完成,图五中的三弟同理。所以在flex布局中要小心使用行号;

  flex布局中行高和高度同时使用结果分析:

  • 只设置行高:项目总行高小于容器高度时,项目按照垂直轴方向在容器内排列,当项目总行高大于容器高度时,大于容器高度项目溢出容器。

  • 只设置高度:项目总高度小于容器高度时,项目按照垂直轴方向在容器内排列,当项目总高度大于容器高度时候,项目在容器中均匀排列,项目总高度最大值为容器高度,不随高度增加无限增加,项目不会溢出容器。

  • 行高高度同时设置:项目行高及高度总值均小于容器高度时,按高度排列,行高不影响span高度,只改变内容位置。项目总高度及总行高均大于容器高度时,项目溢出容器,见图四图五;

  2.2 flex-wrap属性

flex-wrap属性为当总项目宽度超过容器宽度时候是否换行及换行方式,其中包含3个值。(以主轴水平为例)

1. nowrap  //默认属性 不换行,各个项目在容器内被压缩;
2. wrap   //项目总宽度超过容器时进行换行;
3. wrap-reverse  //超出部分自下而上,沿主轴方向排列
复制代码

image.png

   2.3 flex-flow属性 

flex-flow属性值为flex-direction || flex-wrap两种属性的缩写,默认值为 row || nowrap。

1. .box {
2.    flex-flow: row wrap-reverse;
3. }
复制代码

  2.4 justify-content属性 

flex-flow属性值为沿主轴对齐方式,其中包含5种属性值;(主轴为水平轴为例)

1. flex-start        //项目以主轴起点对齐;(左对齐)
2. flex-end         //项目以主轴终点对齐;(右对齐) 
3. center         //项目在主轴居中对齐;
4. space-between    //项目以主轴起点终点为起始点,中间等分对齐;
5. space-around     //项目等分对齐,首尾项目距离边框之和为中间项目间距一半;
复制代码

image.png

justify-content属性值space-around中关于结论“首个及末尾项目距离边框距离为中间项目间距一半”验证。

下面我们有请圆圈家族中的四兄弟,验证过程演示如下:首先选取前三个项目,图八中的第一幅图,其中容器宽度为500px,圆形直径为100px,可以推断出,项目间距约等于66.66px,根据我们的结论首末项目距离边框距离应为33.33px,在下面的第二幅图中加入了四弟,并且设置了它的定位属性,将left值设置为33.33px,变有了我们第三幅图的结果,四弟将三弟覆盖。justify-content属性值space-around中关于结论“首个及末尾项目距离边框距离为中间项目间距一半”验证。

下面我们有请圆圈家族中的四兄弟,验证过程演示如下:首先选取前三个项目,图八中的第一幅图,其中容器宽度为500px,圆形直径为100px,可以推断出,项目间距约等于66.66px,根据我们的结论首末项目距离边框距离应为33.33px,在下面的第二幅图中加入了四弟,并且设置了它的定位属性,将left值设置为33.33px,变有了我们第三幅图的结果,四弟将三弟覆盖。

image.png

  2.5 align-items属性

flex-flow属性值为沿交叉轴对齐方式,其中包含5种属性值;(交叉轴为垂直方向为例)

1.  flex-start   //项目以交叉轴起点对齐;(上对齐)
2.  flex-end    //项目以交叉轴终点对齐;(下对齐)
3.  center     //项目在交叉中居中对齐;  
4.  baseline    //项目沿着其中第一行文字基线对齐; 
5.  stretch    //项目未设置交叉轴方向具体尺寸时(本例子为高度),项目该尺寸占满整个容器;
(stretch有换行时,例如项目为两行,项目高度都为容器高度1/2)
复制代码

image.png

  2.6 align-content属性 

align-content属性值为多行项目时沿交叉轴对齐方式,项目为单行时,属性值无效应使用align-items,其中包含6种属性值;(交叉轴为垂直方向为例) 

1. flex-start      //多行项目以交叉轴起点对齐;(上对齐)
2. flex-end       //多行项目以交叉轴终点对齐;(下对齐)
3. center        //项目在交叉轴中间居中对齐;
4. space-between    //首末行项目分别位于交叉轴起点终点,中间行等分,进行对齐;
5. space-around     //项目等分对齐,【首末行距离边框为中间项目间距的一半】;
6. stretch        //未设置高度时,项目占满整个容器,有多行时,等分容器高度;
复制代码

image.png

  3. 项目属性(子属性:Properties for the Children)

项目属性包含有六个属性:

1. order
2. flex-grow
3. flex-shrink
4. flex-basis
5. flex
6. align-self
复制代码

 3.1 order属性

  order属性可以用来定义项目的顺序,order的值越小,项目在主排列中的顺序越靠前,所有项目默认值为0;

image.png

  3.2 flex-grow属性

flex-grow属性为项目的放大比例,规定了项目在各自占用多少剩余可用空间大小,属性值为数字没有单位,负数(Negative numbers)是无效的,默认为0,此时项目size为自身尺寸,不会方法。

如果所有项目flex-grow设置为1,容器中剩余空间将被等分给项目,若其中有一个项目的value值为2,该项目占据的空间,则为其它项目的2倍。

If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least)。(转)

image.png

容器宽度为500px,圆设置直径为100px,不难算出剩余宽度为100px,图十三中圆形各自宽度为125px,图十四中大哥宽度为140px,其余宽度为120px,从而不难看出,flex-grow属性值是将容器剩余空间宽度按flex-grow值得比例分配。

  3.3.flex-shrink属性

flex-shrink属性为项目的缩小比例,只有在项目宽度之和大于容器的时候才会依据flex-shrink值发生收缩,默认值(default value)为1,负数(negative numbers)无效,默认情况下所有项目都可以被缩放,但是如果设置为0,该项目将维持最初设置尺寸,不被压缩。

image.png

图十五中的七兄弟被flex-shrink均为默认值缩放后的效果,不难算出每个宽度为500/7=71.43px,项目宽度按照容器宽度压缩值相等。虽然我们知道当flex-shrink值不同时也会被压缩,那么是根据什么进行的压缩呢?压缩值又是多少呢?

image.png

从图十七中我们可以看出兄弟中大哥宽度为500px,其余六兄弟宽度为75px,flex-shrink属性和flex-grow属性定义正好相反,是将项目size之和超出容器部分尺寸根据flex-shrink值按比例进行压缩,以沿宽度方向压缩为例进行分析: 圆设置宽度为100px,项目个数为7个,总宽度应为700px,实际容器宽度为500px,超出容器部分为200px,压缩因子(flex-shrink值)分别为2:1:1:1:1:1:1;

压缩值分别为:   
   大哥    200/(2+1+1+1+1+1+1)*2=50px;        
   二弟    200/(2+1+1+1+1+1+1)*1=25px;    
   三弟    200/(2+1+1+1+1+1+1)*1=25px;
   四弟    200/(2+1+1+1+1+1+1)*1=25px;
   五弟    200/(2+1+1+1+1+1+1)*1=25px;
   六弟    200/(2+1+1+1+1+1+1)*1=25px;
   七弟    200/(2+1+1+1+1+1+1)*1=25px;
复制代码

项目实际宽度分别为50px,75px,75px,75px,75px,75px,75px。注意:宽度计算时边框包含在内。

image.png

  3.4 flex-basis属性

flex-basis属性定义了在项目按照缩放因子(shrink factor)或者放大因子(grow factor)分配剩余空间之前,项目的最初尺寸,可以和宽度和高度属性取相同的值(例如200px),flex-basis设置的长度值优先级高于width,不会被width,height覆盖。它的默认值为auto,即项目原来的size。

image.png

  3.5 flex属性(弹性盒伸缩基准值)

flex属性是flex-grow,flex-shrink,flex-basis属性的简写,默认值0 1 auto, 第二个和第三个参数是可选的(flex-shrink,flex-basis),flex-basis值可以是百分比可以为具体数值,百分比为相对于flex盒子。这个属性还可以设置为auto(1 1 auto)none(0 0 auto),建议优先W3C推荐使用这种简短属性,而不是单独的三个分离的属性,浏览器会自己解析剩余部分。

image.png

有以下三种情况:

  • 当flex为单一非负数字值(无法取到负值,被禁止),对flex-grow进行设置flex-shrink值为1,flex-basis值为0%;
  • 当flex为两位非负数字时,分别对flex-grow和flex-shrink进行设置,flex-basis值仍为0%;
  • 当flex单一非负长度或者百分比,对flex-basis值进行设置;

  3.6 align-self属性

align-self属性值定义某个项目在容器内与交叉轴的对其方式,项目设置的align-self值可以覆盖align-items的值,默认值为auto,代表继承父元素的align-items属性值,该属性有6个属性值,除了auto其余属性值和容器属性的align-items值相同。(详见2.5、align-items属性)

1. auto
2. flex-start 
3. flex-end 
4. center  
5. baseline 
6. stretch
复制代码

flex 布局.png

参考文章:

文章分类
前端
文章标签