flexbox顾名思义flexible box弹性盒子,是css3中定义的一种新的布局方式。通过在某元素上使用display: flex;即可把该元素定义为flex容器 ( flex container ),而容器的所有子元素就是flex项目 ( flex item )。再介绍flex语法之前,先来看看一个重要的东西。

flex轴线

flex-axis
在flex容器里,存在两条轴,main axiscross axis,又分别叫做主轴和交叉轴。主轴之所以叫做主轴而不叫做x轴,是因为主轴不一定是在水平线上的,也有可能是垂直方向上,比如当flex-direction: column;的时候,主轴就是在垂直方向上。另外主轴和交叉轴都是有方向的,flex项目就是沿着主轴方向进行布局。主轴默认方向是从左到右,交叉轴则是从上到下。

css3里关于flexbox定义了2类的样式,分别是作用于flex容器上的和作用于flex项目上的。

flex容器

能作用到flex容器上的样式有这么几个:flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content。看到这么几个东西,别被它们吓坏了,多读几遍你就能猜个八九不离十它们是干嘛用的了。下面我们一一来介绍这些样式。

flex-direction

相信你也大概知道了这个样式的作用了,对了就是和方向有关的。flex-direction这个样式就是用来控制main axis的方向的,默认值row,表示水平从左到右。

  • row,默认的属性值,水平方向,从左到右
  • column,垂直方向,从上到下
  • row-reverse,水平方向,从右到左
  • column-reverse,垂直方向,从下到上
1
2
3
4
ul {
display: flex;
flex-direction: row; /* column || row-reverse || column-reverse */
}

来一张图,你就更好理解了:
flex-direction

flex-wrap

flex-wrap规定了flex项目在主轴上是按照一行还是多行显示。

  • nowrap,默认属性,单行显示,会尽力的压缩每个flex项目直到刚好容下里面的内容,实在压缩不了的时候flex项目就可能会溢出容器。
  • wrap,允许多行显示,当一行显示不下的时候,会变成多行显示。
  • wrap-reverse,多行显示,且行的显示顺序是从下到上,即第一行显示在容器的底部。
1
2
3
4
ul {
display: flex;
flex-wrap: nowrap; /* wrap || wrap-reverse */
}

flex-wrap

flex-flow

flex-flow是一个复合属性,是由flex-directionflex-wrap组成的属性。如果只定义了一个属性,那么另外一个属性取默认值。且属性书写顺序没有特别要求。

  • row nowrap,这是默认属性值
1
2
3
4
ul {
display: flex;
flex-flow: row wrap;
}

flex-flow

justify-content

justify-content规定了flex项目在主轴的对齐方式。比如当flex-direction被设置为column时,justify-content定义的是垂直方向上的对齐方式。

  • flex-start, 默认属性值,flex项目将向着主轴起始位置对齐
  • flex-end, flex项目将向着主轴结束位置对齐
  • center, flex项目将在主轴上居中对齐
  • space-between, flex项目将在主轴上以相同的间距贴着轴的两端对齐
  • space-around, flex项目将在主轴上以相同的间距靠着两端对齐,且第一个头尾项目和轴的两端之间存在间距,间距是两个项目间距的一半
1
2
3
4
ul {
display: flex;
justify-content: center;
}

justify-content

align-items

居然有主轴上的对齐方式,那么肯定也有相关的属性是用来定义交叉轴上的对齐规则的。和justify-content一样,align-items也有5个属性定义,其中flex-startflex-endcenter是一样的,就不多介绍了。来说说两个不同的:

  • stretch,默认属性值,flex项目在交叉轴上的尺寸如果没有指定或者是被设置为auto,那么它将在这个方向上尽量延伸,直到靠着容器边界,但是同时延伸的程度也会受到max-height或者max-width的影响
  • baseline,flex项目在交叉轴上的对齐方式将是由每个项目内容的基线决定
1
2
3
4
ul {
display: flex;
align-items: flex-start;
}

align-items

align-content

理解了justify-contentalign-items的对齐方式,再来看align-content就容易理解多了。它只作用于容器,且只能是存在多个行的容器。注意这里的行是相对于交叉轴来说的。属性值有6个:flex-startflex-endcenterstretchspace-betweenspace-around,这些对齐方式上面都介绍过了,大同小异。其中默认值是stretch。结合下图来加深理解:

1
2
3
4
5
ul {
display: flex;
flex-wrap: wrap;
align-content: space-around
}

align-content

flex项目

上面介绍了定义在flex容器上的css属性,规范了整个容器里所有项目的全局呈现。这样不够灵活多变,不足以表现某些需要特别显示的项目,所以针对这一现状,w3c社区又推出了一套作用于flex项目上的css属性。他们分别是:align-selforderflex-growflex-shrinkflex-basisflex等css属性。

align-self

align-self规定了单个flex项目在交叉轴上的对齐方式,属性值可以是下面一个:flex-startflex-endcenterstretchbaselineauto,其中auto为默认属性值,如果被设置为了auto,那么该flex项目最终的对齐方式将是由容器的align-items决定。

1
2
3
4
5
6
ul {
display: flex;
}
ul li {
align-self: center;
}

align-self

order

order定义了flex项目在容器里的排列顺序。取值可以是负整数、0、正整数,默认取值是0。数值越大越靠近轴向的末端,数值相同则按照html里的顺序排列。

1
2
3
4
5
6
ul {
display: flex;
}
ul li {
order: 2;
}

order

flex-grow

flex-grow规定了flex项目的伸展性,其值只能是0或者正整数,默认值是0。如果一个flex项目同时设置了width和值为正整数的flex-grow属性,则width属性将失效。取值如果是0表示不进行伸展;如果是正整数,则会进行伸展,且伸展的尺寸将和数值的大小有关,值越大,伸展得越大。伸展的具体计算数值是该项目占所有可伸展项目总和的比与这些所有可伸展项目占的尺寸的乘积。
flex-grow

flex-shrink

与伸展相对应的属性是flex-shrink,定义了项目的收缩性,值也只能是0或者正整数,默认值是1。如果是0表示不进行收缩,如果是正整数则表示进行收缩。如果一个项目同时显示设置了尺寸和收缩值为1,那么该项目将进行收缩,定义的尺寸将失效。
项目能够进行收缩的前提是必须产生溢出,即所有项目所占尺寸之和必须大于容器尺寸。这个时候容器里所有可收缩的项目就需要通过收缩来消化掉这部分溢出的尺寸。而每个项目具体的收缩量则由其设置的收缩比例决定,数值越大,收缩得越厉害。比如一个容器的尺寸是400px,只有2个项目且尺寸都是300px,收缩比例是1比3,那么容器将溢出200px,所以第一个项目需要收缩50px,第二个项目需要收缩150px,那么收缩完成后它们占据的尺寸分别是250px和150px。
flex-shrink

flex-basis

flex-basis定义了项目在伸缩之前的初始尺寸,可以是长度设置(pxremem等);可以是用百分比基于父级来计算尺寸;也可以是默认的auto,表示其尺寸由内容决定。除了auto外,如果尺寸溢出容器了,那么设置了flex-basis的项目间,则会根据每项设置的基准值,按比率伸缩剩余空间。
flex-shrink

flex

flex是一个复合属性,是由flex-growflex-shrinkflex-basis组成的。

  • flex-grow,用来指定扩展比率,在flex属性中该值如果被省略则默认为1
  • flex-shrink,用来指定收缩比率,在收缩的时候收缩比率会以伸缩基准值加权,在flex属性中该值如果被省略则默认为1
  • flex-basis,用来指定伸缩基准值,即在根据伸缩比率计算出剩余空间的分布之前,表示尺寸的起始数值。在flex属性中该值如果被省略则默认为0%。在flex属性中该值如果被指定为auto,则伸缩基准值的计算值是自身的width 设置,如果自身的宽度没有定义,则长度取决于内容。

一些缩写说明:

  • flex: 1, 则其计算值为1 1 0%
  • flex: auto, 则其计算值为1 1 auto
  • flex: none, 则其计算值为0 0 auto
  • flex: 0 auto 或者flex: initial, 则其计算值为0 1 auto
    flex

兼容性

flex布局在现代浏览器中兼容性还是比较令人满意的。可以去caniuse里看看,或者直接看这个用flex布局写的案例catty-music
caniuse

参考文章