flexbox
顾名思义 flexible box
弹性盒子,是 css3
中定义的一种新的布局方式。通过在某元素上使用 display: flex;
即可把该元素定义为 flex
容器 ( flex container
),而容器的所有子元素就是 flex
项目 ( flex item
)。再介绍 flex
语法之前,先来看看一个重要的东西。
flex 轴线
在 flex
容器里,存在两条轴,main axis
和 cross axis
,又分别叫做主轴和交叉轴。主轴之所以叫做主轴而不叫做 x
轴,是因为主轴不一定是在水平线上的,也有可能是垂直方向上,比如当 flex-direction: column;
的时候,主轴就是在垂直方向上。另外主轴和交叉轴都是有方向的,fle
x` 项目就是沿着主轴方向进行布局。主轴默认方向是从左到右,交叉轴则是从上到下。
css3
里关于 flexbox
定义了 2
类的样式,分别是作用于 flex
容器上的和作用于 flex
项目上的。
flex 容器
能作用到 flex
容器上的样式有这么几个:flex-direction
,flex-wrap
,flex-flow
,justify-content
,align-items
和 align-content
。看到这么几个东西,别被它们吓坏了,多读几遍你就能猜个八九不离十它们是干嘛用的了。下面我们一一来介绍这些样式。
flex-direction
相信你也大概知道了这个样式的作用了,对了就是和方向有关的。flex-direction
这个样式就是用来控制 main axis
的方向的,默认值 row
,表示水平从左到右。
- row,默认的属性值,水平方向,从左到右
- column,垂直方向,从上到下
- row-reverse,水平方向,从右到左
- column-reverse,垂直方向,从下到上
1 | ul { |
来一张图,你就更好理解了:
flex-wrap
flex-wrap
规定了 flex
项目在主轴上是按照一行还是多行显示。
nowrap
,默认属性,单行显示,会尽力的压缩每个flex
项目直到刚好容下里面的内容,实在压缩不了的时候flex
项目就可能会溢出容器。wrap
,允许多行显示,当一行显示不下的时候,会变成多行显示。wrap-reverse
,多行显示,且行的显示顺序是从下到上,即第一行显示在容器的底部。
1 | ul { |
flex-flow
flex-flow
是一个复合属性,是由 flex-direction
和 flex-wrap
组成的属性。如果只定义了一个属性,那么另外一个属性取默认值。且属性书写顺序没有特别要求。
row nowrap
,这是默认属性值
1 | ul { |
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 | ul { |
align-items
居然有主轴上的对齐方式,那么肯定也有相关的属性是用来定义交叉轴上的对齐规则的。和 justify-content
一样,align-items
也有 5
个属性定义,其中 flex-start
,flex-end
和 center
是一样的,就不多介绍了。来说说两个不同的:
stretch
,默认属性值,flex
项目在交叉轴上的尺寸如果没有指定或者是被设置为auto
,那么它将在这个方向上尽量延伸,直到靠着容器边界,但是同时延伸的程度也会受到max-height
或者max-width
的影响baseline
,flex
项目在交叉轴上的对齐方式将是由每个项目内容的基线决定
1 | ul { |
align-content
理解了 justify-content
和 align-items
的对齐方式,再来看 align-content
就容易理解多了。它只作用于容器,且只能是存在多个行的容器。注意这里的行是相对于交叉轴来说的。属性值有 6 个:flex-start
,flex-end
,center
,stretch
,space-between
和 space-around
,这些对齐方式上面都介绍过了,大同小异。其中默认值是stretch
。结合下图来加深理解:
1 | ul { |
flex 项目
上面介绍了定义在 flex
容器上的 css
属性,规范了整个容器里所有项目的全局呈现。这样不够灵活多变,不足以表现某些需要特别显示的项目,所以针对这一现状,w3c
社区又推出了一套作用于 flex
项目上的 css
属性。他们分别是:align-self
,order
,flex-grow
,flex-shrink
,flex-basis
和 flex
等 css
属性。
align-self
align-self
规定了单个 flex
项目在交叉轴上的对齐方式,属性值可以是下面一个:flex-start
,flex-end
,center
,stretch
,baseline
和 auto
,其中 auto
为默认属性值,如果被设置为了 auto
,那么该 flex
项目最终的对齐方式将是由容器的 align-items
决定。
1 | ul { |
order
order
定义了 flex
项目在容器里的排列顺序。取值可以是负整数、0、正整数,默认取值是 0。数值越大越靠近轴向的末端,数值相同则按照 html
里的顺序排列。
1 | ul { |
flex-grow
flex-grow
规定了 flex
项目的伸展性,其值只能是 0
或者正整数,默认值是 0
。如果一个 flex
项目同时设置了width
和值为正整数的 flex-grow
属性,则 width
属性将失效。取值如果是 0
表示不进行伸展;如果是正整数,则会进行伸展,且伸展的尺寸将和数值的大小有关,值越大,伸展得越大。伸展的具体计算数值是该项目占所有可伸展项目总和的比与这些所有可伸展项目占的尺寸的乘积。
flex-shrink
与伸展相对应的属性是 flex-shrink
,定义了项目的收缩性,值也只能是 0
或者正整数,默认值是 1
。如果是 0
表示不进行收缩,如果是正整数则表示进行收缩。如果一个项目同时显示设置了尺寸和收缩值为 1
,那么该项目将进行收缩,定义的尺寸将失效。
项目能够进行收缩的前提是必须产生溢出,即所有项目所占尺寸之和必须大于容器尺寸。这个时候容器里所有可收缩的项目就需要通过收缩来消化掉这部分溢出的尺寸。而每个项目具体的收缩量则由其设置的收缩比例决定,数值越大,收缩得越厉害。比如一个容器的尺寸是 400px
,只有 2
个项目且尺寸都是 300px
,收缩比例是 1
比 3
,那么容器将溢出 200px
,所以第一个项目需要收缩 50px
,第二个项目需要收缩 150px
,那么收缩完成后它们占据的尺寸分别是 250px
和 150px
。
flex-basis
flex-basis
定义了项目在伸缩之前的初始尺寸,可以是长度设置(px
、rem
和 em
等);可以是用百分比基于父级来计算尺寸;也可以是默认的 auto
,表示其尺寸由内容决定。除了 auto
外,如果尺寸溢出容器了,那么设置了 flex-basis
的项目间,则会根据每项设置的基准值,按比率伸缩剩余空间。
flex
flex
是一个复合属性,是由flex-grow
、flex-shrink
和 flex-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
布局在现代浏览器中兼容性还是比较令人满意的。可以去 caniuse
里看看,或者直接看这个用 flex
布局写的案例 catty-music