flex弹性布局

参考文章:https://www.cnblogs.com/zhouchenkai/p/17514903.html

一、flex布局的概念

Flexbox布局也叫Flex布局,弹性盒子布局。它的目标是提供一个更有效地布局、对齐方式,并且能够使父元素在子元素的大小未知或动态变化情况下仍然能够分配好子元素之间的间隙。主要思想是使父元素能够调整子元素的宽度、高度、排列方式,从而更好的适应可用的布局空间。设定为flex布局的元素能够放大子元素使之尽可能填充可用空间,也可以收缩子元素使之不溢出。

Flex布局更适合小规模的布局,可以简便、完整、响应式的实现各种页面布局。但是,设为Flex布局以后,其子元素的floatclearvertical-align属性将失效。Flex弹性盒模型的优势在于只需声明布局应该具有的⾏为,⽽不需要给出具体的实现⽅式,浏览器负责完成实际布局,当布局涉及到不定宽度,分布对⻬的场景时,就要优先考虑弹性盒布局。

Flex布局是一个完整的模块,它包括了一套完整的属性。其中采用 Flex 布局的元素,称为 Flex 容器,简称”容器“。它的所有子元素就是容器成员,称为 Flex 项目,简称”项目“。

注意点:当设置为flex布局后其子元素的floatclearvertical-align属性将失效。

关键词:

  • 容器:采用flex布局的称为容器
  • 项目:容器下面的子元素称为项目

image-20231106134250399

  • 容器默认存在两个轴:水平轴(main axis)垂直轴(cross axis)。 项目默认水平轴
    • img
    • main axis: Flex 父元素的主轴是指子元素布局的主要方向轴,它由属性flex-direction来确定主轴是水平还是垂直的,默认为水平轴。
    • main-start & main-end: 分别表示主轴的开始和结束,子元素在父元素中会沿着主轴从main-start到main-end排布。
    • main size: 单个项目占据主轴的长度大小。
    • cross axis: 交叉轴,与主轴垂直。
    • cross-start & cross-end: 分别表示交叉轴的开始和结束。子元素在交叉轴的排布从cross-start开始到cross-end。
    • cross size: 子元素在交叉轴方向上的大小。

二、容器元素属性

想要让项目使用flex布局需要给容器定义:

1
2
3
4
5
.container{
display: flex
// 行内块元素使用
dispaly: inline-flex
}

1. 容器属性

容器属性一共有六个

分别为:

  • flex-direction :主要用于控制子项目的排序方向 默认水平排序
  • flex-wrap :主要控制子项目还不换行的问题 默认不换行

  • flex-flowflex-diractionflex-wrap的简写形式 flex-flow:<flex-diraction> | <flex-wrap>

  • justify-content :主要控制子项目的对齐方式 默认水平对齐

  • align-items :主要控制子项目的交叉轴方向(默认指垂直方向)对齐方向
  • align-content :这个属性只在有多个flex-direction方向时有效,即flex-wrap属性为换行时有效

2. flex-direction:主轴方向

flex-direction属性决定了主轴的方向,所有容器中的项目都会根据主轴方向来排列。

属性:

  1. row(默认值):Flex 项目水平排列,起点在左端,终点在右端。主轴从左到右。
  2. row-reverse:Flex 项目水平排列,起点在右端,终点在左端。主轴从右到左。
  3. column:Flex 项目垂直排列,起点在顶部,终点在底部。主轴从上到下。
  4. column-reverse:Flex 项目垂直排列,起点在底部,终点在顶部。主轴从下到上。
  • row
1
2
3
.container{
flex-direction: row; // 默认值,从左至右排列
}

img

  • row-reverse
1
2
3
.container{
flex-direction: row-reverse; // 从右至左排列
}

img

  • column
1
2
3
.container{
flex-direction: column; // 从上至下排列
}

img

  • column-reverse
1
2
3
.container{
flex-direction: column-reverse; // 从下至上排列
}

img

3. flex-wrap:换行

flex-wrap属性决定了换行相关的策略。它决定了当弹性容器的宽度不足以容纳所有子元素时,是否允许子元素换行并如何排列。

属性:

  1. nowrap(默认值):子元素不换行,尽可能地将它们放在一行内,即使溢出弹性容器的边界。
  2. wrap:如果子元素在一行内放不下,将它们进行换行,从新行开始排列。
  3. wrap-reverse:与 wrap 相同,但换行时的排列顺序与正常顺序相反。
  • nowrap
1
2
3
.container{
flex-wrap: nowrap; // 默认值,不换行,即使定义了子项目的宽度,也会自动压缩
}

img

  • wrap
1
2
3
.container{
flex-wrap: wrap; // 换行
}

img

  • wrap-reverse
1
2
3
.container{
flex-wrap: wrap-reverse; // 换行,且行的排列倒叙
}

img

4. flex-flow

  • 这个属性是flex-direction和flex-wrap的简写形式,语法为:
1
2
3
.container{
flex-flow: (flex-direction) || (flex-wrap);
}

5. justify-content:主轴对齐

justify-content是flex布局中的重要属性之一,用于定义和调整弹性容器中项目在主轴上的对齐方式。它控制项目沿着主轴的分布方式,包括项目之间的间距、对齐和对齐方式的调整。

属性:

  1. flex-start(默认值):将项目对齐到弹性容器的起始位置。项目靠主轴起始端对齐。
  2. flex-end:将项目对齐到弹性容器的末尾位置。项目靠主轴末尾端对齐。
  3. center:将项目在主轴上居中对齐。项目在主轴上平均分布,两端留有相同的空白。
  4. space-between:将项目在主轴上平均分布,并使项目之间的间距相等。首个项目对齐到主轴起始端,最后一个项目对齐到主轴末尾端。
  5. space-around:将项目在主轴上平均分布,并使项目之间的间距相等。首尾两端的间距是相邻项目间距的一半。
  6. space-evenly:将项目在主轴上平均分布,并使项目之间的间距相等。首尾两端和相邻项目之间的间距相等。不常用
  • flex-start
1
2
3
.container{
justify-content: flex-start; // 默认值,flex-direction方向相同对齐
}

img

  • flex-end
1
2
3
.container{
justify-content: flex-end; // flex-direction方向相反对齐
}

img

  • center
1
2
3
.container{
justify-content: center; // flex-direction方向居中对齐
}

img

  • space-between
1
2
3
.container{
justify-content: space-between // flex-direction方向两端对齐
}

img

  • space-around
1
2
3
.container{
justify-content: space-around; // 每个项目的左右间隔相等对齐,会导致项目之间的距离比项目和边框之间的距离大一倍
}

img

6. align-items: 交叉轴(默认垂直轴)单行对齐属性

与justify-content对应的,align-items用于定义和调整弹性容器中项目在交叉轴上的对齐方式,它同样也控制项目沿着交叉轴的分布方式,包括项目之间的间距、对齐和对齐方式的调整。

属性:

  1. stretch(默认值):将项目在交叉轴上拉伸以填充整个弹性容器。项目将沿交叉轴方向拉伸至与容器的交叉轴尺寸相等。
  2. flex-start:将项目对齐到弹性容器的交叉轴起始位置。项目靠交叉轴起始端对齐。
  3. flex-end:将项目对齐到弹性容器的交叉轴末尾位置。项目靠交叉轴末尾端对齐。
  4. center:将项目在交叉轴上居中对齐。项目在交叉轴上平均分布,上下留有相同的空白。
  5. baseline:将项目在交叉轴上与其基线对齐。项目的基线与其他项目的基线对齐。
  • flex-start
1
2
3
.container{
align-items: flex-start; // 与当前flex-direction方向的垂线方向同向对齐
}

img

  • flex-end
1
2
3
.container{
align-items: flex-end // 与当前flex-direction方向的垂线方向反向对齐
}

img

  • center
1
2
3
.container{
align-items: center; // 与当前flex-direction方向的垂线方向居中对齐
}

img

  • baseline
1
2
3
.container{
align-items: baseline; // 与子项目的第一行文字的基线对齐
}

img

  • stretch
1
2
3
.container{
align-items: stretch; // 默认值,当子项目没有设置flex-direction方向上的大小值时,会自动填满容器在flex-direction方向上可用容量
}

flex-direction为row时:

img

flex-direction为column时:

img

7. 交叉轴多行对齐align-content属性

在上文的flex-wrap中,换行显示的盒子出现了一些空隙,这就和align-content有关系,align-content是CSS中用于控制flex容器中多行项目的对齐方式的属性。它适用于具有多行内容的flex容器,并决定了这些行在容器中的项目在交叉轴上的对齐方式。

这个属性只在有多个flex-direction方向时有效,即flex-wrap属性为换行时有效

以下是align-content的一些常用的取值:

  1. flex-start:将多行项目对齐到容器的起始位置。第一行将与容器的顶部对齐。
  2. flex-end:将多行项目对齐到容器的结束位置。最后一行将与容器的底部对齐。
  3. center:将多行项目在容器中垂直居中对齐。
  4. space-between:在容器中平均分布多行项目,使第一行在容器的顶部,最后一行在容器的底部,剩余的行平均分布在中间。
  5. space-around:在容器中平均分布多行项目,使每行周围具有相等的空间,包括顶部和底部。
  6. space-evenly:在容器中平均分布多行项目,使每行之间和周围都具有相等的空间。
  7. stretch(默认值):在容器中平均分布多行项目,项目将被拉伸以填充整个容器的高度。
  • flex-start
1
2
3
.container{
align-content: flex-start; // 与当前flex-direction方向的垂线方向同向对齐
}

img

  • flex-end
1
2
3
.container{
align-content: flex-end; // 与当前flex-direction方向的垂线方向反向对齐
}

img

  • center
1
2
3
.container{
align-content: center; // 与当前flex-direction方向的垂线方向居中对齐
}

img

  • space-between
1
2
3
.container{
align-content: space-between; // 与当前flex-direction方向的垂线方向两端对齐
}

img

  • space-around
1
2
3
.container{
align-content: space-around; // 每个项目的上下间距相同,和justify-content一样,因为中间的间距叠加,首尾的间距是中间间距的一半
}

img

  • space-evenly
1
2
3
.container{
align-content: space-evenly; // 当align-content的值取space-evenly时,所有交叉轴上的间距相同
}

img

三、项目属性

子项目总共有6个属性可以定义。
第一个:order,表示子项目的排列顺序,数值越小排名越靠前,值为整数,默认值为0,可以取负值。

第二个:flex-grow,表示子项目根据剩余空间的放大比例,默认值为0,即表示即使有剩余空间,也不放大。

第三个:flex-shrink,表示子项目根据剩余空间大小的缩小比例,默认值为1,即表示剩余空间不足时,该项目会缩小。不能使用负值。

第四个: flex-shrink,用于指定项目在容器中缩小的能力,当 flex 容器空间不足时候,单个元素的收缩比例

第五个:flex,这个属性是flex-grow,flex-shrink,flex-basis这3个属性的简写形式

第六个:align-self,该属性表示单个项目的对齐方式,属性值与容器元素的align-item完全相同,默认值为auto,与父元素表现一致。

1. 改变项目的显示顺序order属性

order属性用于控制Flex容器中子元素的排序。默认情况下,Flex容器中的子元素按照它们在HTML源代码中的顺序进行排列,但是使用order属性,我们可以改变这个顺序

每个Flex项目的order属性默认值是0。你可以为项目设定任意整数值,数值可以是正数、0或者负数。具有较小order值的元素将被优先排列,具有相同order值的元素将按照它们在HTML源代码中的原始顺序排列。

1
2
3
.item1{
order: -2;
}

img

2. 子项目扩张flex-grow属性

flex-grow用于设置或检索flex容器中的flex子项目的能力,以根据其在flex容器中的空间比例来伸展和占用空间。

flex-grow属性的默认值为0,表示子项目将不会伸展以填充容器。

1
2
3
4
5
6
7
.container div{
flex-grow: 1; // 当所有项目的flex-grow都为1时,它们将平分剩余空间。
}

.container div.item4{
flex-grow: 2; // 当有一个项目的flex-grow2时,表示它得到的剩余空间为其他项目的2倍。
}

img

3. 子项目收缩flex-shrink属性

flex-shrink用于指定项目在容器中缩小的能力,当 flex 容器空间不足时候,单个元素的收缩比例。当父元素的宽度小于子元素宽度之和并且超出了父元素的宽度时,flex-shrink 就会按照一定的比例进行收缩:将子元素宽度之和与父元素宽度的差值按照子元素 flex-shrink 的值分配给各个子元素,每个子元素原本宽度减去按比例分配的值,其剩余值为实际宽度。

flex-shrink的默认值是1,也就是说,当子元素宽度的和超出父容器的时候,所有子项目都等比例的缩小

1
2
3
.container div.item4{
flex-shrink: 0; // 当某个项目的flex-shrink0,而其他项目都为1时,表示该项目不会缩小其他项目缩小。
}

img

4. 子项目初始尺寸flex-basis属性

flex-basis,表示在分配当前flex-direction方向上的多余空间之前,这个项目要占据多少空间。浏览器会根据这个属性来计算当前flex-direction方向上是否有多余的空间。默认值为auto。即使用项目本身的大小,设置了width(或height,根据flex-direction方向决定)时,会使用width值,没有设置时,会使用项目的内容大小。

flex-basis并不能保证项目的实际大小,当当前flex-direction方向上的剩余空间不足时,项目仍然会被压缩,flex-basis表示的是一种理想的大小,可以看成是项目还未放入容器时应该表现出的大小。最大最小值属性(min-width,max-width,min-height,max-height)仍然可以限制flex-basis的值。

flex-basis指定的值是根据box-sizing的类型来指定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 由于容器剩余大小无法满足给定的值,所有项目会按照其flex-basis的值等比例缩放。
.container div.item1{
flex-basis: 1000px;
}
.container div.item2{
flex-basis: 2000px;
}
.container div.item3{
flex-basis: 3000px;
}
.container div.item4{
flex-basis: 4000px;
}

img

5. 联合写法flex属性

flex属性是flex-grow,flex-shrink,flex-basis三个属性的简写,用于控制子项目的缩放行为和初始尺寸。

flex的完整写法是 flex:,也就是一共有3个值要去设置,分别按顺序对应flex-grow,flex-shrink,flex-basis,而在日常工作中并不会经常写完整的写法,而较常用的是flex:1或者50%这种写法。

flex-grow和flex-shrink可以同时设置,但是对于一个元素,同时只会有其中一者生效,因为flex-grow需要有剩余空间才能进行拉伸分配而flex-shrink需要子元素宽度之和超过父元素(溢出)才会收缩,一个盒子要么空间不足,要么就空间超出,不可能既有剩余空间又宽度之和超出父元素

flex属性的常用值有

  1. flex: auto: 此值表示元素可以根据可用空间进行伸缩,可以扩展也可以收缩。
  2. flex: initial: 此值将 flex-grow、flex-shrink 和 flex-basis 设置为默认值。flex-grow 为 0,flex-shrink 为 1,flex-basis 为 auto。
  3. flex: none: 此值表示元素不应该伸缩。flex-grow 和 flex-shrink 均为 0,flex-basis 为其本来的大小。
  4. flex: 数字/百分比/长度

简单语法:

1
2
3
.item{
flex: (flex-grow) || (flex-shrink) || (flex-basis);
}

该属性的默认值是flex: 0 1 auto,有两个关键字值,none和auto。

1
2
3
4
5
6
.item{
flex: none; // 表示 flex: 0 0 auto,即表示不放大,不缩放
}
.item{
flex: auto; // 表示 flex: 1 1 auto,即表示放大,缩放
}

flex还有以下特殊情况:

1
2
3
4
5
6
7
8
9
10
.item{
flex: 0; // 值为0时,表示flex: 0 1 0,即直接以内容宽度显示。
flex: 0%; // 值为一个百分值时,表示flex-basis的值,此时flex-grow值为1flex-shrink值为1,表示flex: 1 1 0%,即放大,缩放。
flex: 1px; // 值为一个带单位的大小值时,与百分值相同。
flex: 1; // 值为一个大于0的数字时,表示flex-grow的值,此时flex-shrink值为1flex-basis值为0%,即flex: 1 1 0%,即放大,缩放。
flex: 1 2; // 值为两个大于0的数字时,表示flex-growflex-shrink的值,此时flex-basis值为0%,即flex: 1 2 0%,即放大,缩放。
flex: 1 0; // 值为大于0的数字和0时,表示flex: 1 1 0,即放大,缩放。
flex: 0 1; // 值为0和大于0的数字时,表示flex: 0 1 0,即直接以内容宽度显示。
flex: 0 30px; // 值为非负数字(0和正数)和一个带单位的大小值时(无论先后顺序),表示flex-growflex-basis的值,表示flex: 0 1 30px
}

flex:auto代表的是 flex:1 1 auto(flex-grow:1, flex-shrink: 1, flex-basis: auto) ,表示的是根据具体空间来进行扩展或者收缩

img

img

flex:initial(默认值)代表的是 flex:0 1 auto(flex-grow:0, flex-shrink: 1, flex-basis: auto) ,表示子项目不会在有剩余空间时候扩张,但是超出时会要收缩。

img

img

flex:none 代表的是 flex:0 0 auto(flex-grow:0, flex-shrink: 0, flex-basis: auto),表示子项目不会扩张也不会收缩,保持原有尺寸

在超出父容器的时候,也会继续保持原有的尺寸

img

其他值:

如果只写一个值,类似于flex: 1 这种,分2种情况

  1. 如果写的是数字比如,flex: 1,flex: 2,flex: 3这种那设置的是flex-grow的值,其他2个值取默认
  2. 如果写的是百分比(flex: 20%)或者是长度(flex: 100px),就是设置的flex-basis属性,其他2个值取默认

如果只写两个值,第一个值对应的是flex-grow,第二个值对应2种情况

  1. 如果第二个值写的是数字比如,flex: 1,flex: 2,flex: 3这种那设置的是flex-shrink的值
  2. 如果写的是百分比(flex: 20%)或者是长度(flex: 100px),就是设置的flex-basis属性

如果写三个值,对应地去设置flex-grow、flex-shrink 和 flex-basis

6. 子项目单独对齐align-self属性

align-self属性用于调整Flex容器中单个项目(Flex项)的垂直对齐方式。它允许你为单个项目指定不同于其它项目的垂直对齐方式。align-self属性可以应用于任何Flex项,并覆盖容器级别的垂直对齐设置(通过align-items属性设置)

常用的值有:

  1. auto(默认值):继承自父容器的align-items属性。
  2. flex-start:项目与容器的顶部对齐。
  3. flex-end:项目与容器的底部对齐。
  4. center:项目在容器的垂直中心对齐。
  5. baseline:项目与容器的基线对齐。
  6. stretch:项目被拉伸以填充整个容器的高度。

针对第二个子项目,设置了align-self: center,第三个子项目设置了align-self: flex-end

这里是单行的align-self效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.parent {
display: flex;
align-items: flex-start;
width: 400px;
height: 200px;
background-color: blueviolet;
}

.child {
box-sizing: border-box;
width: 100px;
height: 50px;
background-color: aqua;
border: 1px solid black;
}

#two{
align-self: center;
}
#three{
align-self: flex-end;
}

img

如果在父容器中加入换行,效果如下

img