定向爆破:Flex布局全解析

209 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

Flexbox是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力;区别于传统布局 display + position + flex的相对繁琐,也区别于Grid二维布局。是一种轻便、易用的布局方式。

1. 布局的骨架:主轴、交叉轴

你要是任务主轴一定是水平横向的,交叉轴一定是纵向的,那你就错了。主轴由 flex-direction 定义,交叉轴轴垂直于主轴。由于flex-direction默认是row,所以主轴默认是水平横向的,相应交叉轴是垂直纵向的。

flex-direction 可以取 4 个值

  • row
  • row-reverse
  • column
  • column-reverse

使用 弹性布局 的所有属性都跟这两根轴线有关,比如:对齐 flexbox 里面的元素(项目)是很重要的,flexbox 的特性就是沿着主轴或者交叉轴对齐之中的元素。

2. 布局的起点、终点:起止线

起止线可以分为主轴的起止线,交叉轴的起止线;它不仅和flex-direction的值有关,还和文档的书写模式有关,我们关注汉语、英语的书写模型,则flex-direction 是 row 时,主轴的起始线是左边,终止线是右边。

qzx1.png

3. 布局的两个成员:容器、项目

弹性布局有唯一的两个成员,我们所有的相关弹性布局书写都是针对这两个成员写的;在任意的元素上写 display: flex / inline-flex,则这个元素就是弹性布局里的容器,容器中的直系子元素就会变为 flex 元素,称为 项目;在弹性布局的容器、项目上有初始属性值,所以只在 容器 元素上加 display: flex样式,弹性布局就有一些表现:

这些表现以及对应的初始值有:

  • 项目排列为一行。 (这是因为初始值:flex-direction: row)
  • 项目从主轴的起始线开始依次排列。 (这也是flex-direction 设为 row 造成的)
  • 项目不会在主维度方向拉伸,但是可以缩小。 (这是因为初始值:flex-grow: 1;flex-shrink: 0)
  • 项目的高度是被拉伸,来填充交叉轴大小。 (这是因为初始值:align-items: stretch;align-self: auto;)
  • 项目的初始大小由其内容的大小确定。 (这是因为初始值:flex-basis: auto)
  • 所有项目的总宽度大于容器的宽度时,会溢出容器,而不是换行。 (这是因为初始值:flex-wrap: nowrap)

3.1 容器的属性

容器上属性总共有6个属性,他们分别如下:

  1. flex-direction 定义弹性布局主轴方向
  2. flex-wrap 定义弹性布局换行时的表现
  3. flex-flow flex-direction 和 flex-wrap 组合简写
  4. align-items 项目在交叉轴上的对齐方式
  5. justify-content 项目在主轴方向的对齐方式
  6. align-content 多行布局时,即flex-wrap: wrap,有换行时,多个主轴如何分配空间

3.2 项目的属性

项目上的属性也是总共有6个,分别如下:

  1. order 项目排序
  2. flex-grow 有剩余空间时,项目按比例伸长
  3. flex-shrink 空间不够时,项目按比例缩小
  4. flex-basis 计算空间时项目的大小
  5. align-self 单个项目重写容器的align-items属性
  6. flex flex-grow, flex-shrink, 和 flex-basis的组合简写

4. 布局的最引人注目的特性:对齐

首先不得不再次强调一下,flex-direction 的值决定着主轴、和交叉轴、起止点,即决定了对齐的作用。

弹性布局的对齐概念可以细分理解有以下四种:

4.1 主轴上项目的对齐

主轴上对齐通过属性justify-content ,他的初始值是 flex-start

justify-content 的属性有:

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • stretch
  • space-evenly (没有在 flexbox 特性中定义)

比如 justify-content: space-between,则项目主轴上排布如图(flex-direction: row):

dq1.png

4.2 交叉轴上项目的对齐

交叉轴上对齐通过属性align-items控制,他的初始值是 stretch

align-items的属性值有:

  • flex-start: 项目的开始端的对齐
  • flex-end: 项目的结束端对齐
  • center: 项目居中对齐
  • stretch: 项目撑满 flex 容器,默认值
  • baseline: 项目的基线对齐

比如 align-items: center,则项目交叉轴上排布如图(flex-direction: row);

dq2.png

4.3 同一个容器内,有多行时,多个行(多个主轴)如何对齐

当容器内的项目总宽度之和大于容器的宽度,并且容器设置属性flex-wrap: wrap;时,一行显示不下的项目会折行显示,此时具有多个flex主轴,则多条主轴的对齐方式是通过属性 align-content控制的。

align-content 属性的值如下:

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • stretch
  • space-evenly (没有在 Flexbox 特性中定义)

比如:align-content: space-between,则多个主轴排布如图(flex-direction: row);

dq3.png

4.4 控制交叉轴(纵轴)上的单个 flex 项目的对齐

单个项目在交叉轴上对齐使用 align-self 属性。align-self的默认属性值是auto,表示继承容器设置的交叉轴对齐属性align-items的属性值;

align-self的属性值比align-items的属性值多一个,有:

  • auto: 默认值
  • flex-start: 项目的开始端的对齐
  • flex-end: 项目的结束端对齐
  • center: 项目居中对齐
  • stretch: 项目撑满 flex 容器,默认值
  • baseline: 项目的基线对齐

比如下图第三个项目设置align-self: center(flex-direction: row);

dq4.png

5. 弹性布局在多行布局中的表现

弹性布局多行布局是通过flex-wrap;align-content;两个属性来控制的;

6. 弹性布局的常见简写

  1. flex-flow
flex-flow 属性是 flex-directionflex-wrap 属性的复合属性;
flex-flow: row wrap;表示flex-direction: row; flex-wrap: wrap;主轴方向是row,主轴上空间不够时,折叠换行;
此属性加在容器上;
  1. flex: 1 1 auto
  flex-grow: 1; flex-shrink: 1; flex-basis: auto; 的缩写,表示项目伸长比例是1,缩放比例是1,初始计算大小是项目内容的大小;
  此属性加在项目上;
  1. flex: auto

此种写法等同于:flex: 1 1 auto

  1. flex: initial
initial是flex的默认属性
此种写法等同于:flex: 0 1 auto/或者flex: initial initial initial
表示flex-grow: 0; flex-shrink: 1; flex-basis: auto; 容器有剩余空间时其尺寸不会增长(flex-grow: 0),容器尺寸不足时尺寸会收缩变小(flex-shrink: 1),项目初始大小自适应于其内容;
此属性加在项目上;
  1. flex: 1
此种写法等同于:flex: 1 1 0
表示flex-grow: 1; flex-shrink: 1; flex-basis: 0; 容器有剩余空间时其尺寸会增长(flex-grow: 1),容器尺寸不足时尺寸会收缩变小(flex-shrink: 1),项目初始大小是0,因此项目尺寸表现为最小内容宽度;
此属性加在项目上;
  1. flex: none
此种写法等同于:flex: 0 0 auto
表示flex-grow: 0; flex-shrink: 0; flex-basis: auto; 容器有剩余空间时其尺寸不会增长(flex-grow: 0),容器尺寸不足时尺寸不会收缩变小(flex-shrink: 0),项目没有弹性,项目初始大小自适应于其内容,表现为最大内容宽度;
此属性加在项目上;
  1. flex: 0
此种写法等同于:flex: 0 1 0
表示flex-grow: 0; flex-shrink: 1; flex-basis: 0; 容器有剩余空间时其尺寸不会增长(flex-grow: 0),容器尺寸不足时尺寸会收缩变小(flex-shrink: 1),项目初始大小是0,因此项目尺寸表现为最小内容宽度;
此属性加在项目上;

7. 弹性布局中的剩余空间是什么?

Flex 布局中有 flex 容器和 flex 子元素(项目),flex 子元素(项目)包含在 flex 容器中,那么当 flex 子元素(项目)在主轴上的尺寸(大小)之和小于 flex 容器 的尺寸时,flex 容器中就会有多余的空间没有被填充,这些空间就被叫做剩余空间,对剩余空间的分配,是对齐的关键;

flex 子元素(项目)大小的定义是由 flex-basis定义的,初始值flex-basis: auto表示项目的内容撑起来的大小;你可以设置0或者具体的数值如100px等作为项目的大小,这是浏览器计算剩余空间首先要确认的。