Flex 布局

前言

页面布局,是前端开发中的一个重点。

传统的 PC 端布局方式有:

  • 基于 CSS 盒模型,依赖 CSS 的 display、position 和 float 属性的固定布局
  • 基于百分比的流体布局

很明显,以上两种布局方式不太适合移动端的页面布局。

最近这几年,基于 CSS 媒体查询 和 流体布局 的响应式布局使得移动端的页面布局变得生机勃勃。

不过,有的时候,似乎固定布局、流体布局、响应式布局都不太合适某个需求。
这里所说的不合适,可能是固定布局这种明显的不合适,
也可能是流体布局、响应式布局这种可以耗费一定的时间可以实现需求但是实现成本略高的不合适。

既然存在问题,世界这么大,肯定就会有聪明的人提出解决方案,所以前端开发领域有了一种新的布局方案:Flex 布局。

顺便提一句,今年做的丁香调查问卷的项目,是基于 rem 的固定布局和 Flex 布局混合使用的。
各种布局方案灵活混合使用,可以更轻松的实现产品需求,提高开发效率。这或许是“知行合一”思想的一个实践。

Flexible 这个词用得很好,可以理解为:给盒状模型提供最大的灵活性。

核心思想:基于元素个数不同,自动填充容器。

基础知识

  • Flex容器(flex container):采用Flex布局的元素,称为Flex容器,简称”容器”
  • Flex项目(flex item):Flex容器的所有子元素自动成为容器成员,称为Flex项目,简称”项目”
  • 主轴(main axis):Flex容器默认水平方向有一根轴,称为主轴
  • 交叉轴(cross axis):Flex容器默认垂直方向有一根轴,称为交叉轴
  • main start:主轴开始的位置与Flex容器边框的交叉点
  • main end:主轴结束的位置与Flex容器边框的交叉点
  • cross start:交叉轴开始的位置与Flex容器边框的交叉点
  • cross end:交叉轴结束的位置与Flex容器边框的交叉点
  • 默认情况下,项目沿主轴排列且项目都排在一条轴线上
  • main size:单个项目占据的主轴空间
  • cross size:单个项目占据的交叉轴空间

Flex容器的属性

Flex容器共有6个属性:

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

flex-direction

决定主轴的方向(即项目的排列方向)。它可能有4个值:

  • row(默认值):主轴为水平方向,起点在左端
  • row-reverse:主轴为水平方向,起点在右端
  • column:主轴为垂直方向,起点在上沿
  • column-reverse:主轴为垂直方向,起点在下沿

flex-wrap

定义如果一条轴线排不下,如何换行。它可能取三个值:

  • nowrap(默认):不换行
  • wrap:换行,第一行在上方
  • wrap-reverse:换行,第一行在下方

flex-flow

flex-flow 属性是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为:row nowrap

justify-content

定义了项目在主轴上的对齐方式。它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右:

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

align-items

定义项目在交叉轴上如何对齐。它可能取5个值,具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下:

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。该属性可能取6个值:

  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。

Flex项目的属性

Flex容器共有6个属性:

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self

order

定义项目的排列顺序。数值越小,排列越靠前,默认为0。

flex-grow

定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。
如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

flex-shrink

定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。
如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

flex-basis

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。
浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

flex

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

align-self

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

示例

1
2
3
4
.box {
display: -webkit-flex;
display: flex;
}

等比划分 和 混合划分

1
2
3
4
5
<div class="container">
<div id="box-0"></div>
<div id="box-1"></div>
<div id="box-2"></div>
</div>

等比划分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
display: -webkit-flex;
display: flex;
}

#box-0 {
flex: 1
}

#box-1 {
flex: 2
}

#box-2 {
flex: 1
}

混合划分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
display: -webkit-flex;
display: flex;
}

#box-0 {
width: 100px;
}

#box-1 {
flex: 2
}

#box-2 {
flex: 1
}

居中

1
2
3
4
5
6
.parent {
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
}

参考

Flex 布局教程:语法篇
Flex 布局教程:实例篇

志遥 wechat
微信扫一扫,我在丁香园记公众号等你