Flex 布局

Flex 布局

Flex 布局简介

Flex 布局(Flexible Box)是在 CSS3 中新增加的一种布局模式,是一种一维的布局模型,旨在提供一种更加有效的方式来对一个容器中的子元素进行排列对齐,确保页面可以适应不同的屏幕大小。

弹性盒由弹性容器和弹性元素组成,在 Flex 布局模型中,弹性元素可以在任何方向上排布,它们的尺寸也可以弹性伸缩,既可以增加尺寸以填满未使用的空间,也可以收缩尺寸以避免父元素溢出。子元素的水平对齐和垂直对齐都可以很方便地进行操控,也可以通过水平框和垂直框的嵌套来在两个维度上构建布局。一个含有三个

块的
容器使用了 Flex 布局前后的样式变化如下图所示,右边是应用 Flex 布局之后的样式。

image-20220319145109322

此外,在弹性盒之外以及弹性元素之内的元素是正常渲染的,弹性盒子只定义了弹性元素在弹性容器内的布局。

弹性容器

如何得到弹性容器

我们一般通过将父元素的 display 属性设置为 flex 或者 inline-flex 来设置弹性容器,二者的区别在于前者是 block 而后者是 inline-block。在经过对 display 进行设置之后,我们就得到了一个弹性容器,容器内的元素将会变为弹性元素,此时,所有的弹性元素的 CSS 都会有一个初始值,它们会具有以下特性:

  • 元素排列为一行。

  • 元素从主轴的起始线开始(主轴和交叉轴的知识将会在下面介绍)。

  • 元素不会在主维度方向拉伸,但是可以缩小。

  • 在交叉轴方向,元素若不指定高度则会被拉伸。

  • flex-basis 属性为auto

  • flex-warp 属性为 nowarp

弹性容器相关的一些属性

  • flex-direction

对于弹性布局来说,我们首先要理解两个轴线:主轴和交叉轴,两根轴线呈垂直关系。flex-direction用于定义主轴,主轴指定了弹性容器中子元素的排列方式,决定了他们的排列方向,共有以下四种取值:

1
2
3
.flex-container { 
flex-direction: row | row-reverse | column | column-reverse;
}
  • row 默认值,主轴水平,元素将水平从左到右显示。

  • row-reverserow 相同,但是从右到左显示。

  • column 主轴垂直,元素将从上到下显示。

  • column-reversecolumn 相同,但是从下到上显示。

具体不同方向如下图所示。

image-20220319145528783

交叉轴则是与主轴垂直的轴,默认情况下,元素会延展至交叉轴的末尾。

  • flex-wrap

在初始的时候,我们的弹性盒只有一行,这就造成了默认情况下子元素会缩小以适应容器,有的时候,只有一行的弹性盒会为我们带来很多不便,这时我们就可以修改容器的 flex-wrap 属性。

flex-wrap 共有三个取值:

1
2
3
.flex-container { 
flex-wrap: nowrap | wrap | wrap-reverse;
}

flex-wrap 属性为 wrap 的时候,若弹性容器的宽度小于弹性元素的总宽度,子元素就无法全部显示在一行里,就会发生自动换行。当三个宽度为 180px 的

块在一个宽度为400px的
块中,下图即为将 flex-wrap 属性设置为 wrap 的时候所发生的变化。

image-20220319145649396

  • flex-flow

flex-flow 属性是以上两个属性的简写,第一个指定的值为 flex-direction,第二个指定的值为 flex-wrap

  • align-items

align-items 主要用来设置交叉轴方向上的对齐方式。以下五个参数分别是从交叉轴起始位置开始放置子元素、从交叉轴终止位置开始放置子元素、子元素居中对齐、子元素基线对齐、子元素拉伸占据剩余空间。默认值是 flex-start,即交叉轴起始位置开始放置子元素。几种对齐方式如下所示,顺序与下列代码中参数顺序等同。

1
2
3
.flex-container { 
align-items: flex-start | flex-end | center | baseline | stretch;
}

image-20220319145829345

  • align-content

align-contentalign-items 几乎等同,但是align-content 是操作多行的,对单行弹性盒模型无效(即含有 flex-wrap: nowrap 的弹性盒模型)。除此之外,还多出两个可选值。

1
2
3
.flex-container { 
align-content: flex-start | flex-end | center | baseline | stretch | space-between | space-around;
}

space-between 的效果是,有多余的空间就会平均分布,每个子元素的两边空白保持一致,头尾子元素贴在边缘。

space-around 的效果是,有多余的空间就会平均分布,每个子元素的两边空白保持一致,头尾子元素不会贴在边缘。

  • justify-content

justify-content 设置的是在主轴方向上的对齐方式,其他与 align-items 没有什么不同的地方。

1
2
3
.flex-container { 
justify-content: flex-start | flex-end | center | space-between | space-around;
}

总体来说,对于一个弹性容器,有以下几种属性可以设置。

属性 描述
flex-direction 指定弹性容器中子元素排列方式
flex-wrap 设置弹性盒子的子元素超出父容器时是否换行
flex-flow flex-directionflex-wrap 的简写
align-items 设置弹性盒子元素在交叉轴方向上的对齐方式
align-content 修改 flex-wrap 属性的行为,类似 align-items, 但不是设置子元素对齐,而是设置行对齐
justify-content 设置弹性盒子元素在主轴方向上的对齐方式

弹性元素

为了更好地控制弹性元素的显示,我们可以对弹性元素的以下几种属性进行更改。在考虑对属性进行更改之前,我们首先要明白什么是可用空间,因为以下的前三个重要属性的主要作用就是对可用空间进行了更改。如图所示,当一个容器承载 3 个宽度为 100px 的元素时,可用空间即为 200px。

image-20220319150044202

在我们对 flex 的三个属性进行更改的时候,本质上其实就是控制可用空间在这几个元素之间的分配。在理解了这一点之后,让我们来具体研究一下这些元素的属性。

  • flex-basis

flex-basis 属性定义了这个子元素的空间大小,该属性的默认值是 auto ,如果元素设定了宽度的话,flex-basis 的值将会为它的宽度,上图中,由于元素 a 设定了宽度为 100px,则它的 flex-basis 值即为 100px。

若将 flex-basiswidth 一起设置,则 flex-basis 会决定元素宽度的最小值,width 则会决定元素宽度的最大值。

  • flex-grow

flex-grow 属性的默认值为 0,也就是不支持扩展。若设置为正整数(不支持负值),则会以 flex-basis 为基础沿主轴方向增长并且占据可用空间。

flex-grow 允许元素按照比例来分配空间。如果第一个元素的 flex-grow 值为 1,第二个为 2,第三个为 1,则第二个元素将会占可用空间的 2/4,另外的元素则会占据 1/4 的空间。

  • flex-shrink

flex-shrinkflex-grow 相对,主要用来处理弹性元素在主轴上收缩的问题,它的默认值为 1。如果弹性容器中排列弹性元素的空间不足,则可以将 flex-shrink 属性设置为正整数,这样它所占有的空间就会缩小到 flex-basis 以下,它和 flex-grow 一样,也是按比例缩小的,数值越大,这个元素收缩的程度越大。

  • flex

flex 属性是 flex-growflex-shrinkflex-basis 属性的简写,相比于三个属性分别使用,我们在开发的时候更倾向于使用单独的 flex 属性来制定其他三个属性。

1
2
3
.flex-container .flex-item { 
flex: flex-grow flex-shrink flex-basis | auto | initial | inherit;
}

flex 有几个预定义的属性,如下所示:

  • initial: 相当于 0 1 autoflex 元素尺寸不会超过 flex-basis,但是会收缩来防止元素溢出。

  • auto: 相当于 1 1 auto,与 initial 唯一的不同是,它可以拉伸也可以收缩。

  • none: 相当于 0 0 auto,它是不可伸缩的。

  • 正整数: 相当于 1 1 0,可以在 flex-basis 为 0 的基础上进行伸缩。

  • order

order 的值为一个数值,可以用来决定弹性元素的排列顺序,数值越小越靠前。

  • align-self

align-self 属性可以为子元素单独设置对齐方式,默认值是 auto,它的优先级高于父容器的 align-items,所以会替代掉父容器的值。但是如果 align-self 和父容器的 align-content 同时存在,则会采用父容器的 align-content 值。

1
2
3
.flex-container { 
align-items: auto | flex-start | flex-end | center | baseline | stretch;
}

弹性元素属性如下表所示。

属性 描述
order 设置弹性盒子的子元素排列顺序。
flex-grow 设置或检索弹性盒子元素的扩展比率。
flex-shrink 指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。
flex-basis 用于设置或检索弹性盒伸缩基准值。
flex 设置弹性盒子的子元素如何分配空间。
align-self 在弹性子元素上使用。覆盖容器的 align-items 属性。