Flexbox布局也叫Flex布局,弹性盒子布局。它的目标是提供一个更有效地布局、对齐方式,并且能够使父元素在子元素的大小未知或动态变化情况下仍然能够分配好子元素之间的间隙。主要思想是使父元素能够调整子元素的宽度、高度、排列方式,从而更好的适应可用的布局空间。设定为flex布局的元素能够放大子元素使之尽可能填充可用空间,也可以收缩子元素使之不溢出。
Flex布局更适合小规模的布局,可以简便、完整、响应式的实现各种页面布局。但是,设为Flex布局以后,其子元素的float、clear和vertical-align属性将失效。Flex弹性盒模型的优势在于只需声明布局应该具有的⾏为,⽽不需要给出具体的实现⽅式,浏览器负责完成实际布局,当布局涉及到不定宽度,分布对⻬的场景时,就要优先考虑弹性盒布局。
Flex布局是一个完整的模块,它包括了一套完整的属性。其中采用 Flex 布局的元素,称为 Flex 容器,简称"容器"。它的所有子元素就是容器成员,称为 Flex 项目,简称"项目"。
- Flex容器(Flex Container):采用Flex布局的元素,通过给该元素设置
display
属性的值为flex
或inline-flex
,来定义一个Flex容器。flex
值表示该容器是一个块级元素,而inline-flex
值表示该容器是一个行内元素。 - Flex项目(Flex Items):Flex容器的所有子元素自动成为Flex项目。这意味着,在Flex布局中,你直接对容器的子元素进行布局、对齐和分配空间,而不是传统布局中可能需要的嵌套块级元素或行内元素。
在Flex布局中,确实存在两个主要的轴:主轴(main axis)和交叉轴(cross axis),但它们的方向并不总是水平轴和垂直轴,这取决于flex-direction
属性的设置。
-
主轴(Main Axis):这是Flex容器的主方向轴,Flex项目将沿着这条轴进行排列和尺寸调整。默认情况下,如果
flex-direction
的值为row
(默认值),那么主轴就是水平轴,从左到右排列项目。但是,如果flex-direction
被设置为column
,那么主轴就变成垂直轴,从上到下排列项目。 -
交叉轴(Cross Axis):这是与主轴垂直的轴,Flex项目在交叉轴上的尺寸和对齐方式由交叉轴相关的属性控制(如
align-items
和align-self
)。如果主轴是水平轴,那么交叉轴就是垂直轴;如果主轴是垂直轴,那么交叉轴就是水平轴。
因此,说“项目默认沿主轴排列(水平轴)”并不完全准确,因为主轴的方向可以是水平的也可以是垂直的,这取决于flex-direction
的设置。默认情况下,由于flex-direction
是row
,所以主轴是水平的,项目沿水平轴从左到右排列。但是,一旦改变了flex-direction
的值,主轴的方向和项目的排列方向也会相应改变。
- 主轴(Main Axis)
- 定义:Flex父元素的主轴是子元素布局的主要方向轴。这个方向决定了Flex项目(子元素)如何排列。
- 确定方向:主轴的方向由
flex-direction
属性确定。默认值为row
,表示主轴是水平方向,从左到右排列项目。如果flex-direction
被设置为column
,则主轴变为垂直方向,从上到下排列项目。 - 主尺寸(Main Size):Flex项目在主轴上占据的空间大小称为主尺寸。这通常与项目的宽度(对于水平主轴)或高度(对于垂直主轴)相关。
- 主轴的开始与结束(Main-start & Main-end)
- 定义:
main-start
和main-end
分别表示主轴的开始和结束位置。Flex项目将沿着主轴从main-start
到main-end
进行排列。 - 位置关系:对于水平主轴(
flex-direction: row
),main-start
通常位于容器的左侧,main-end
位于右侧。对于垂直主轴(flex-direction: column
),main-start
位于容器的顶部,main-end
位于底部。
- 定义:
- 交叉轴(Cross Axis)
- 定义:交叉轴是垂直于主轴的轴。它的方向由主轴的方向决定。
- 作用:交叉轴主要用于控制Flex项目在主轴方向之外的对齐和尺寸。
- 交叉轴的开始与结束(Cross-start & Cross-end)
- 定义:
cross-start
和cross-end
分别表示交叉轴的开始和结束位置。Flex项目在交叉轴上的排列虽然不如主轴上那么直接,但这些位置仍然对项目的对齐和尺寸有重要影响。 - 位置关系:对于水平主轴(
flex-direction: row
),交叉轴是垂直的,cross-start
位于容器的顶部,cross-end
位于底部。对于垂直主轴(flex-direction: column
),交叉轴是水平的,cross-start
位于容器的左侧,cross-end
位于右侧。
- 定义:
- 交叉尺寸(Cross Size)
- 定义:交叉尺寸是指Flex项目在交叉轴方向上占据的空间大小。
- 影响因素:交叉尺寸的大小可能受到Flex项目自身的尺寸属性(如
width
、height
)、Flex容器的对齐属性(如align-items
)、以及Flex项目的align-self
属性等因素的影响。
1 在使用Flex布局时,首先需要给父元素(即容器)指定为Flex布局
给父元素指定为Flex布局通常是通过设置该元素的display
属性为flex
(表示块级Flex容器)或inline-flex
(表示行内Flex容器)来实现的。默认情况下,如果不特别指定,display: flex;
会被设置为块级Flex容器。
<div class="container"></div>
.container {
display: flex | inline-flex;
}
如果我们使用块状元素,比如div标签,就可以使用flex,如果使用行内元素,就可以使用inline-flex。多数情况下,我们会使用display: flex;
父元素(容器)可以设置以下六个属性:
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
flex-direction
属性用于定义 Flex 容器中项目的排列方向,它决定了主轴的方向。这个属性有四个可能的值,每个值都对应着不同的排列方式:
-
flex-direction: row;
:- 这是默认值。
- Flex 项目将沿着水平主轴从左到右排列。
- 主轴的起点位于容器的左边缘。
- 交叉轴是垂直的。
-
flex-direction: row-reverse;
:- Flex 项目将沿着水平主轴从右到左排列。
- 主轴的起点位于容器的右边缘。
- 交叉轴仍然是垂直的,与
row
方向相反。
-
flex-direction: column;
:- Flex 项目将沿着垂直主轴从上到下排列。
- 主轴的起点位于容器的上边缘。
- 交叉轴现在是水平的。
-
flex-direction: column-reverse;
:- Flex 项目将沿着垂直主轴从下到上排列。
- 主轴的起点位于容器的下边缘。
- 交叉轴是水平的,与
column
方向相反。
通过调整
flex-direction
的值,您可以灵活地控制 Flex 容器内部项目的排列方式,以适应不同的布局需求。这个属性是 Flex 布局中非常基础和重要的一个属性,因为它直接决定了项目的排列方向和主轴的方向。
flex-wrap
属性用于指定 Flex 容器中的项目是否可以在必要时换行到下一行。这个属性有三个值,每个值都定义了不同的换行行为:
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
-
flex-wrap: nowrap;
:-
这是默认值。
-
Flex 项目将在一行内显示,不会换行。
-
如果容器的宽度不足以容纳所有项目,则项目会根据
flex-shrink
属性的值缩小,以尝试适应容器宽度。
-
如果项目无法进一步缩小以适应容器,或者容器设置了固定的宽度,则项目可能会溢出容器。
min-width:
-
-
flex-wrap: wrap;
:- Flex 项目将在必要时换行到下一行。
- 换行后的第一行将位于容器的顶部(即主轴的起点方向)。
- 如果有足够的空间,后续的行将堆叠在上一行的下方。
- 这允许容器根据项目的数量和尺寸自动调整高度(对于水平主轴)或宽度(对于垂直主轴)。
-
flex-wrap: wrap-reverse;
:- Flex 项目同样会在必要时换行,但与
wrap
不同的是,第一行将位于容器的底部(或主轴的结束方向)。 - 这意味着换行后的行将堆叠在容器的底部,并且向上堆叠(对于水平主轴)或向左堆叠(对于垂直主轴)。
- 这允许实现一些特殊的布局效果,如底部对齐的卡片列表或垂直堆叠的列。
通过调整
flex-wrap
的值,您可以控制 Flex 容器内项目的换行行为,从而创建更加灵活和适应性强的布局。 - Flex 项目同样会在必要时换行,但与
justify-content
属性用于定义 Flex 容器中的项目在主轴上的对齐方式。这个属性有五个值,每个值都提供了不同的对齐方式,这里以水平方向为主轴(即 flex-direction: row;
)进行说明:
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
-
justify-content: flex-start;
:- 默认值。
- 项目在主轴上向一端的对齐,具体来说是左对齐(如果主轴是水平的)。
- 项目之间的间隔是它们各自占用的空间。
-
justify-content: flex-end;
:- 项目在主轴上向另一端的对齐,具体来说是右对齐(如果主轴是水平的)。
- 类似于
flex-start
,但项目是在主轴的另一端对齐。
-
justify-content: center;
:- 项目在主轴上居中对齐。
- 如果容器有足够的空间,项目将均匀分布在主轴的中间位置。
-
justify-content: space-between;
:- 项目之间的间隔相等,且项目在主轴的两端对齐。
- 第一个项目与容器的开始边界贴合,最后一个项目与容器的结束边界贴合,剩余的空间在其余项目之间平均分配。
-
justify-content: space-around;
:- 每个项目两侧的间隔相等。
- 因此,项目之间的间隔比项目与容器边界的间隔大一倍。
- 这导致第一个项目前的空间和最后一个项目后的空间是项目之间间隔的一半。
align-items
属性定义了 Flex 容器中的项目在交叉轴上的对齐方式。当容器的 flex-direction
设置为 row
时,交叉轴是垂直的(即垂直于主轴)。以下是 align-items
属性的五个可能值及其效果:
-
align-items: flex-start;
- 项目在交叉轴的起点对齐(顶部或左边,取决于主轴的方向,但在这里我们假设主轴是水平的,所以是顶部)。
- 如果容器的高度设置为 100px,而项目的高度分别为 20px、40px、60px、80px、100px,则所有项目的顶部都会对齐在容器的顶部,且项目之间不会有额外的垂直间隔(除非有额外的CSS规则或Flex容器的其他属性导致间隔)。
-
align-items: flex-end;
- 项目在交叉轴的终点对齐(底部或右边)。
- 同样地,如果容器的高度为 100px,而项目的高度各异,则所有项目的底部都会对齐在容器的底部,导致较短的项目在顶部有额外的空间。
-
align-items: center;
- 项目在交叉轴的中点对齐。
- 如果容器的高度为 100px,无论项目的高度如何,它们都会以容器的中心点为基准垂直居中对齐。
-
align-items: baseline;
- 项目的基线对齐。这通常意味着文本的基线将对齐,但如果项目中有不同的对齐方式(例如,有些项目包含文本,有些则不包含),则效果可能不如预期。
- 注意,
baseline
对齐并不总是意味着所有项目的底部都会在同一水平线上,而是依赖于项目的具体内容和对齐方式。
-
align-items: stretch;
(默认值)-
如果项目未设置高度或高度设置为
auto
,则项目将被拉伸以填充整个容器的交叉轴长度。
-
如果容器的高度为 100px,且所有项目都没有设置高度或高度设置为
auto
,则所有项目都将被拉伸到 100px 高。但是,如果项目设置了最小高度(min-height
)或最大高度(max-height
),则这些值可能会限制拉伸的程度。
-
align-content
属性在 CSS Flexbox 和 Grid 布局中用于控制当存在多条轴线时,这些轴线如何在交叉轴(cross axis)上对齐。对于 Flexbox 来说,它主要用于多行容器(即,当容器的 flex-wrap
属性设置为 wrap
或 wrap-reverse
时,子项超出单行容器范围而自动换行的情况)。
在 Flexbox 布局中,align-content
属性控制的是多行子项在交叉轴(默认是垂直方向,但如果主轴是垂直的,则交叉轴是水平方向)上的对齐方式。当 Flex 容器内的子项不足以占满一行时,这个属性不起作用,因为它主要关注的是多行内容。
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
align-content
属性的常用值包括:
flex-start
:将项目对齐到容器的开始端。flex-end
:将项目对齐到容器的结束端。center
:将项目在容器的交叉轴居中对齐。space-between
:项目之间的间隔相等,项目与容器边缘之间没有间隔。space-around
:项目两侧的间隔相等。因此,项目之间的间隔是项目与容器边缘间隔的两倍。stretch
(默认值,Flexbox 专用):如果项目未设置高度或设为 auto,将拉伸填充整个容器的交叉轴。Grid 布局中此值表现可能不同,取决于其他属性。space-evenly
:项目之间的间隔,以及项目与容器边缘的间隔,都是相等的。
这里以水平方向为主轴时举例,即:flex-direction: row; flex-wrap: wrap;
align-content: stretch
:默认值,轴线占满整个交叉轴。这里我们先设置每个项目都是固定宽度,效果如下:
align-content: flex-start
:从交叉轴开始位置填充
align-content: flex-end
:从交叉轴结尾位置填充
align-content: center
:与交叉轴中点对齐
align-content: space-between
:与交叉轴两端对齐,轴线之前的间隔平均分布
align-content: space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍
2 子元素属性,子元素有以下六个属性
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
Flexbox是一个用于在容器中对齐和分布空间的一维布局方法,即使它们的大小未知或是动态的。下面是每个术语的简要说明:
-
order:
order
属性定义了flex容器中项目的排列顺序。默认情况下,项目按照它们在HTML中出现的顺序排列。通过给项目设置不同的order
值,你可以控制它们的排列顺序。值越小,项目排列越靠前。
-
flex-basis:
flex-basis
属性定义了flex项目在分配多余空间之前,默认占据的主轴空间(main size)。它可以设置为像素值(如20px)、百分比(如50%)或者auto
。默认值为auto
,即项目的本来大小。
-
flex-grow:
flex-grow
属性定义了flex项目的放大比例。它决定了flex项目相对于容器中剩余空间的大小。默认值为0,意味着如果有剩余空间,项目也不会增长。如果所有项目的flex-grow
值都相同,则它们将等分剩余空间。
如果其中一个项目的flex-grow属性设置为2,其他均为1,那么它占据的剩余空间就是其他项目的两倍:
-
flex-shrink:
flex-shrink
属性定义了flex项目的缩小比例。当容器空间不足时,它决定了flex项目如何缩小。默认值为1,意味着如果空间不足,项目将缩小。如果设置为0,则表示项目不会缩小。
-
flex:
flex
属性是flex-grow
、flex-shrink
和flex-basis
的简写,允许你同时设置这三个值。默认值为0 1 auto
,即项目不会增长(除非有空间),但会缩小以适应容器,并且其基础大小是其本来大小。- 对于flex的取值有几种常用的特殊情况:默认值:flex:0 1 auto,即在有剩余空间时,只缩小不放大:
- flex: none,即有剩余空间时,不放大也不缩小,最终尺寸通常表现为最大内容宽度:
- flex: 0,即当有剩余空间时,项目宽度为其内容的宽度,最终尺寸表现为最小内容宽度:
在CSS中,flex
属性是一个简写属性,用于同时设置flex-grow
、flex-shrink
和flex-basis
的值。这三个属性分别控制flex项目的放大比例、缩小比例和基础大小。现在,我们来看你提到的flex: 1
、flex: 0
(这里可能是个简写,因为flex: 0
没有指定flex-basis
,所以它通常不是这么写的,但我们可以理解为flex-grow: 0; flex-shrink: 1; flex-basis: 0%
的一个默认或特定情况下的简写),以及flex: auto
的含义。
flex: 1
flex: 1
是 flex-grow: 1; flex-shrink: 1; flex-basis: 0%
的简写。这意味着:
flex-grow: 1;
:项目将等比例放大以填充可用空间。如果所有项目的flex-grow
值都为1,则它们将平分额外空间(如果有的话)。flex-shrink: 1;
:项目将等比例缩小,以防空间不足。flex-basis: 0%;
:项目的初始大小(即在不考虑额外空间的情况下)基于其内容的自然宽度(在主轴方向上),但这里的0%
实际上意味着在考虑空间分配时,它不考虑项目内容的原始大小。然而,在实践中,如果没有足够的空间让所有项目按自然大小显示,且所有项目的flex-shrink
值都相同,那么它们通常会根据其内容的相对大小来缩小。
flex: 1
是 CSS Flexbox 布局中一个非常常用的简写属性,它结合了flex-grow
、flex-shrink
和flex-basis
三个属性的值。具体来说,flex: 1
等同于flex-grow: 1; flex-shrink: 1; flex-basis: 0%
(尽管flex-basis
的0%
在这里主要是一个起始点,实际尺寸会受内容影响)。
常用案例
1. 弹性增长以填充额外空间
当你希望一组flex项目能够弹性地增长以填充其父容器的额外空间时,flex: 1
非常有用。例如,如果你有一个水平布局的导航栏,其中包含几个导航项,你希望这些项能够均匀地填充整个导航栏的宽度:
<div class="navbar">
<div class="nav-item">Home</div>
<div class="nav-item">About</div>
<div class="nav-item">Services</div>
<div class="nav-item">Contact</div>
</div>
<style>
.navbar {
display: flex;
width: 100%;
}
.nav-item {
flex: 1; /* 使得每个导航项都能弹性增长以填充空间 */
text-align: center; /* 可选,使文本居中 */
}
</style>
在这个例子中,每个 .nav-item
都会根据其父容器 .navbar
的宽度和其他 .nav-item
的数量来弹性增长,从而均匀地填充整个导航栏。
2. 与固定尺寸项目混合使用
flex: 1
也可以与具有固定尺寸的flex项目一起使用。在这种情况下,具有 flex: 1
的项目会首先填充所有固定尺寸项目之后剩余的空间。
<div class="container">
<div class="fixed">Fixed Width</div>
<div class="flexible">Flexible</div>
<div class="flexible">Flexible</div>
</div>
<style>
.container {
display: flex;
width: 100%;
}
.fixed {
width: 100px; /* 固定宽度 */
}
.flexible {
flex: 1; /* 弹性增长以填充剩余空间 */
}
</style>
在这个例子中,.fixed
元素有一个固定的宽度,而两个 .flexible
元素则会弹性增长以填充 .container
剩余的空间。
3. 响应式布局
flex: 1 在构建响应式布局时与媒体查询(Media Queries)结合使用,可以非常灵活地调整flex项目的布局以适应不同屏幕尺寸。下面是一个具体的例子,展示了如何使用flex: 1和媒体查询来创建一个响应式的flex容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/* 基本的flex布局样式 */
.container {
display: flex;
flex-wrap: wrap; /* 允许项目换行 */
padding: 10px; /* 容器内边距 */
}
.item {
flex: 1; /* 默认情况下,所有项目都尝试均等地分配空间 */
min-width: 200px; /* 设置最小宽度,避免内容过于拥挤 */
margin: 10px; /* 项目之间的间距 */
background-color: #f0f0f0; /* 背景色,便于观察 */
text-align: center; /* 文本居中 */
padding: 20px; /* 文本内边距 */
box-sizing: border-box; /* 包含内边距和边框在总宽度内 */
}
/* 媒体查询:屏幕宽度小于600px时 */
@media (max-width: 600px) {
.item {
flex: none; /* 取消弹性增长,每个项目占据整行 */
width: calc(100% - 20px); /* 减去两边的间距 */
}
}
</style>
</head>
<body>
<div class="container">
<div class="item">项目 1</div>
<div class="item">项目 2</div>
<div class="item">项目 3</div>
<!-- 可以根据需要添加更多项目 -->
</div>
</body>
</html>
</style>
在这个例子中,.item
元素在屏幕宽度大于600px时会弹性增长以填充空间,但在小于或等于600px时,它们会停止弹性增长并占据整行,从而实现响应式布局。
flex: 0
(实际应用中不太会这样写)
如果你看到flex: 0
,这实际上不是一个完整的flex
属性简写,因为它没有指定flex-basis
。然而,如果我们假设这是在一个上下文中,其中flex-basis
默认为auto
(这是常见的),那么它可以被理解为flex-grow: 0; flex-shrink: 1; flex-basis: auto
(但请注意,flex-shrink: 1
是默认值,所以只需要指定flex-grow: 0; flex-basis: auto
就足够了)。但通常,你不会仅仅写flex: 0
,因为这可能产生歧义。
flex: auto
flex: auto
是 flex-grow: 1; flex-shrink: 1; flex-basis: auto
的简写。这意味着:
flex-grow: 1;
:项目将等比例放大以填充可用空间。flex-shrink: 1;
:项目将等比例缩小,以防空间不足。flex-basis: auto;
:项目的初始大小是其内容的自然宽度(在主轴方向上)。
这个设置使得flex项目能够根据可用空间进行放大或缩小,同时保持其内容的自然宽度作为起始点。
- align-self:
align-self
属性允许单个flex项目有与其他项目不一样的对齐方式,覆盖align-items
属性在容器上的设置。它适用于flex容器中的单个项目,并且可以设置为auto
(默认值,继承父元素的align-items
属性)、flex-start
、flex-end
、center
、baseline
或stretch
。
Flexbox布局提供了极大的灵活性,允许开发者创建复杂的布局结构,而不需要使用浮动(floats)、定位(positioning)或表格(tables)。
未完待续。。。