前端八股总结CSS分支-flex布局

Last updated on October 28, 2024 pm

整理一下flex布局的知识。

Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。本文给出了 flexbox 的主要特性,更多的细节将在别的文档中探索。

我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。

一、flexbox的两根轴线

当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。主轴由 flex-direction 定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关,所以有必要在一开始首先理解它:flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。

它由四个值定义:

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

如果选择了 row 或者 row-reverse,主轴将沿着行向延伸,交叉轴随之延径向;

选择 column 或者 column-reverse 时,主轴会沿着页面的上下方向延伸。

二、Flex容器

文档中采用了 flexbox 的区域就叫做 flex 容器。为了创建 flex 容器,我们把一个容器的 display 属性值改为 flex 或者 inline-flex。完成这一步之后,容器中的直系子元素就会变为 flex 元素。由于所有 CSS 属性都会有一个初始值,所以 flex 容器中的所有 flex 元素都会有下列行为:

  • 元素排列为一行(flex-direction 属性的初始值是 row)。
  • 元素从主轴的起始线开始。
  • 元素不会在主维度方向拉伸,但是可以缩小。
  • 元素被拉伸来填充交叉轴大小。
  • flex-basis 属性为 auto
  • flex-wrap 属性为 nowrap

这会让你的元素呈线形排列,并且把自己的大小作为主轴上的大小。如果有太多元素超出容器,它们会溢出而不会换行。如果一些元素比其他元素高,那么元素会沿交叉轴被拉伸来填满它的大小。

image-20241028102541209

三、Flex的基本属性

(1)flex-wrap

用于决定子元素是否换行。

  • nowrap(默认):不换行(子元素会缩小以适应容器,无法缩小会溢出)
  • wrap:换行,移除元素会移至下一行
  • wrap-reverse:换行并逆序排列

(2)flex-flow

可以将两个属性 flex-directionflex-wrap 组合为简写属性 flex-flow,第一个指定的值为 flex-direction ,第二个指定的值为 flex-wrap

(3)控制flex元素上的属性

是为了控制元素如何会自动延伸收缩以适应可用空间。(控制元素而非容器

image-20241028142856880
🦔flex-basis

flex-basis 定义了该元素的空间大小,flex 容器里除了元素所占的空间以外的富余空间就是可用空间。该属性的默认值是 auto。此时,浏览器会检测这个元素是否具有确定的尺寸。在上面的例子中,所有元素都设定了宽度(width)为 100px,所以 flex-basis 的值为 100px。

如果没有给元素设定尺寸,flex-basis 的值采用元素内容的尺寸。这就解释了:我们给只要给 Flex 元素的父元素声明 display: flex,所有子元素就会排成一行,且自动分配大小以充分展示元素的内容。

🦔flex-grow

flex-grow 若被赋值为一个正整数,flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的可用空间(available space)。如果有其他元素也被允许延展,那么他们会各自占据可用空间的一部分。

它可以按照比例分配空间,在下面的例子可以看到。

🦔flex-shrink

在计算 flex 元素收缩的大小时,它的最小尺寸也会被考虑进去,就是说实际上 flex-shrink 属性可能会和 flex-grow 属性表现的不一致。因此,我们可以在文章《控制 Flex 子元素在主轴上的比例》中更详细地看一下这个算法的原理。

相反flex-shrink属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间,那么可以把 flex 元素flex-shrink属性设置为正整数来缩小它所占空间到flex-basis以下。与flex-grow属性一样,可以赋予不同的值来控制 flex 元素收缩的程度——给flex-shrink属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。

(就算收缩,如果元素中有子元素,最小的大小不会小于元素中子元素的长度,见例子)

🦔flex属性的简写

大部分这些属性都是混合在一起写的,按照下面的顺序:

1
flex: flex-grow flex-shrink flex-basis

当然也可以使用预定义的简写形式:

  • flex: initial(相当于0 1 auto,默认值)(不会超过它们本身的长度,但是可以收缩
  • flex: auto(相当于 1 1 auto)(可收缩可拉伸)
  • flex: none(相当于 0 0 auto)(不可收缩,也不可拉伸)
  • flex: <positive-number>(相当于 num 1 0)(num表示占几倍的剩余空间)
🦔示例

均设置成initial:(容器大小200px,三个元素大小均50px)

image-20241028144648615

第一个设置成auto:(全设成auto会平分空间)

image-20241028144815014

均设置成auto/none:(容器140,元素仍旧50)

image-20241028144950361

image-20241028145129787

均设置成auto:(容器120,元素50)(缩到最小也无法适应)

image-20241028145059519

分别设置成 1、2、3:(容器300,元素50)

image-20241028145338443

四、元素间的对齐和空间分配

(1)align-items

定义在交叉轴上的对齐方式。

🦒stretch(默认)

拉伸元素来填满flex容器:

image-20241028145859870
🦒flex-start

按照flex容器的顶部对齐:

image-20241028150022317
🦒flex-end

按照最下部对齐:

image-20241028150214847
🦒center

在交叉轴上居中对齐:(即在垂直方向居中)

image-20241028150232063

(2)justify-content

🦒flex-start(默认值)
🦒flex-end
🦒flex-right
🦒flex-left
🦒stretch
🦒center
image-20241028150625147
🦒space-around

每个元素的左右空间相等:

image-20241028150722335
🦒space-between
image-20241028150739876
🦒space-evenly

所有间距都相同

image-20241028151435953

(3)align-self(子元素的属性)

用于对齐单个flex子项。

拥有align-items 的所有属性值,另外还有一个 auto 能重置自身的值为 align-items 定义的值。

image-20241028151745449

(4)align-content

当有多行(多列)元素的时候,设置每行(每列)元素在交叉轴上的对齐方式。

属性值和justify-content一样。

示例几个:

image-20241028152722109image-20241028152826620

(5)没有justify-self怎么办

怎么达到这样的效果?

image-20241028153028418

答案是在three元素上添加margin-left: auto属性。或者Two添加右外边距属性。

五、用flex实现经典布局

image-20241028154132102

(1)HTML

1
2
3
4
5
6
7
8
9
10
<div class="layout">
<nav class="navbar">导航栏</div>
<div class="main">
<aside class="sidebar">侧栏</aside>
<main class="content">
<section>内容块1</section>
<section>内容块2</section>
</main>
</div>
</div>

(2)CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body,html {
height: 100%;
}
/* 布局容器 */
.layout {
display: flex;
flex-direction: column;/* 将导航栏放在上方 */
height: 100vh;/* 占满整个视口高度 */
}

.navbar {
background-color: #333;
color: white;
padding: 10px;
text-align: center;
}
/* 主容器 */
.main {
display: flex;
flex: 1; /* 主容器占满剩余空间 */
}
/* 侧栏 */
.sidebar {
backgroud-color: #f4f4f4;
width: 200px; /* 固定宽度 */
padding: 20px;
}
/* 右侧内容区 */
.content {
display: flex;
flex-direction: column;/* 上下排列内容块 */
flex: 1; /* 占满主容器剩余空间 */
padding: 20px;
gap: 10px;/* 内容块间距 */
}
/* 上下内容块 */
section {
background-color: #ddd;
flex: 1;/* 两个内容块等高 */
padding: 20px;
}

(终于结束了😇,四小时不停敲敲敲,手已断)


前端八股总结CSS分支-flex布局
http://example.com/2024/10/28/前端八股总结CSS分支-flex布局/
Author
Yaodeer
Posted on
October 28, 2024
Licensed under