flex 弹性盒子
在 CSS 中,display: flex
是一种布局模型,用于创建弹性盒子(flexbox)。它定义了一个容器元素及其子元素的布局方式,使其能够更灵活地调整和排列内容。
使用 display: flex
可以将一个容器元素转换为弹性盒子,并控制其中子元素的排列方式、对齐方式以及伸缩行为。
下面是一个示例,展示了如何使用 display: flex
:
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
.container {
display: flex;
}
在上面的示例中,将一个 <div>
元素的 display
属性设置为 flex
,将其转换为一个弹性盒子。
使用 display: flex
后,弹性盒子中的子元素(.item
)可以按照一定的规则进行排列,默认情况下它们将水平排列。弹性盒子还具有一些属性和值,用于控制子元素的布局和行为。
以下是一些常用的弹性盒子属性:
-
flex-direction
:指定子元素的排列方向,可以是row
(水平方向,默认值)、column
(垂直方向)、row-reverse
(水平反向)或column-reverse
(垂直反向)。 -
justify-content
:指定子元素在主轴上的对齐方式,可以是flex-start
、flex-end
、center
、space-between
、space-around
等。 -
align-items
:指定子元素在交叉轴上的对齐方式,可以是flex-start
、flex-end
、center
、baseline
、stretch
等。 -
- 主轴(main axis)和交叉轴(cross axis)。它们用于定义弹性盒子内部元素的排列方式。
- 主轴(Main Axis):
- 主轴是弹性盒子的主要方向,决定了弹性盒子内元素的水平或垂直排列方式。
- 默认情况下,主轴的方向是水平的,从左到右排列(即从起始边(start)到结束边(end))。
- 通过设置
flex-direction
属性,可以改变主轴的方向,可以使其为水平方向(row
或row-reverse
)或垂直方向(column
或column-reverse
)。
- 交叉轴(Cross Axis):
- 交叉轴是与主轴垂直的轴线,与主轴形成一个交叉的关系。
- 交叉轴的方向取决于主轴的方向。如果主轴是水平方向,那么交叉轴就是垂直方向;如果主轴是垂直方向,那么交叉轴就是水平方向。
- 交叉轴的起始边和结束边与主轴的起始边和结束边相对应。
-
flex-wrap
:指定子元素是否换行,可以是nowrap
(不换行,默认值)、wrap
(换行)或wrap-reverse
(反向换行)。 -
align-content
:指定多行子元素在交叉轴上的对齐方式,只在存在多行时生效,可以是flex-start
、flex-end
、center
、space-between
、space-around
等。 -
flex-basis
属性用于指定弹性盒子项目的初始主轴尺寸。它定义了项目在未分配多余空间之前的默认大小。默认情况下,项目的 flex-basis 值为 auto,它将根据项目内容自动计算大小。flex-basis
值可以是一个长度值(如像素或百分比),也可以是关键字auto。例如,flex-basis: 50%
将使项目的初始主轴尺寸占据父容器宽度的一半。
可以使用 CSS
的 order
属性来控制 flex
容器中项目的顺序。默认情况下,项目的 order
值为 0
,你可以为项目设置一个正数或负数的 order
值来改变它们的顺序。具有较小 order
值的项目会排在前面。
需要注意的是,display: flex
是 CSS3 中引入的新特性,部分老旧的浏览器可能不支持该特性或需要使用浏览器前缀。因此,在使用时需要进行浏览器兼容性的考虑。
常见适用情况
弹性盒子(flexbox)是一种强大的布局模型,适用于许多不同的情况。以下是一些常见的情况,其中使用弹性盒子布局可以非常有用:
-
等高的列布局:当希望多个列的高度保持一致时,弹性盒子布局可以方便地实现这一目标。弹性盒子的子元素可以自动撑开,使所有列的高度保持一致。
-
自适应和响应式布局:弹性盒子布局适应不同尺寸的屏幕和设备非常方便。可以使用弹性盒子的属性和值,根据可用空间自动调整和重排子元素。
-
水平和垂直居中:弹性盒子提供了简单的方法来水平和垂直居中元素,无论是在容器内部还是容器本身。
-
项目排序和重新排序:可以使用弹性盒子的
order
属性来更改子元素的顺序,从而改变它们在布局中的位置。 -
间距和对齐控制:弹性盒子的属性可以帮助你精确地控制子元素之间的间距和对齐方式,使布局更加灵活和美观。
-
多列布局:通过设置弹性盒子的
flex-wrap
属性,可以创建多列布局,使多个子元素在容器内自动换行。 -
导航菜单和工具栏:弹性盒子非常适合用于创建导航菜单和工具栏,使项目水平排列,并具有弹性宽度和对齐选项。
-
等宽的网格布局:如果需要创建一个等宽的网格布局,弹性盒子可以简化这个过程,并且在容器尺寸变化时保持网格的均匀分布。
这只是一些弹性盒子布局的常见应用场景,实际上,弹性盒子提供了许多强大的特性和灵活性,可以适应各种布局需求。
flex弹性盒子和传统盒子的区别
使用 flex 弹性盒子(flexbox)和传统的盒子模型(block 和 inline)相比,有以下几个区别:
-
自适应空间分配:在弹性盒子中,子元素的宽度和高度可以根据可用空间进行自适应分配。弹性盒子具有伸缩性,可以根据容器的大小和内容来调整子元素的尺寸。而在传统的盒子模型中,元素的尺寸通常由其内容决定,无法方便地进行自适应调整。
-
方向灵活性:弹性盒子提供了更灵活的方向控制。可以通过设置
flex-direction
属性来改变弹性盒子的主轴方向(水平或垂直),以及交叉轴方向。这样,可以更方便地实现水平布局、垂直布局或者混合布局。而在传统的盒子模型中,水平布局和垂直布局需要使用不同的布局方式(block 或 inline)。 -
对齐和排序控制:弹性盒子提供了更精确的对齐和排序控制。可以使用
justify-content
和align-items
属性来控制子元素在主轴和交叉轴上的对齐方式,实现水平居中、垂直居中等对齐效果。而在传统的盒子模型中,对齐需要通过调整外边距(margin)或使用其他技巧来实现。 -
灵活的顺序控制:弹性盒子允许通过设置
order
属性来改变子元素的顺序,实现灵活的布局调整。可以通过调整元素的order
值来改变它们在布局中的排列顺序。而在传统的盒子模型中,改变元素的顺序通常需要修改 HTML 结构。
需要注意的是,传统的盒子模型在大多数情况下仍然有效,特别是对于简单的布局需求。弹性盒子模型提供了更多的布局控制选项和灵活性,适用于更复杂和动态的布局需求。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="wrapper">
<div class="container1"></div>
<!-- <div class="container2"></div>-->
<!-- <div class="container3"></div>-->
<!-- <div class="container4"></div>-->
</div>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper {
height: 100vh;
display: flex;
/*居中方法一:*/
/*justify-content: center;*/
/*align-items: center;*/
}
.container1 {
width: 200px;
height: 200px;
background: #e57676;
/*居中方法二:*/
margin: auto;
}
</style>
</body>
</html>
margin: auto 是指在主轴和副轴上占据剩余空间。只有一个 auto 相当于占掉上下左右的剩余空间,自然就居中了。
比如使用 margin-left: auto ,就变成了:
所以根据该规则,我们可以:
左右两列布局:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="wrapper">
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
</div>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper {
background: #f0f0f0;
height: 100vh;
display: flex;
/*居中方法一:*/
/*justify-content: center;*/
/*align-items: center;*/
}
.container {
width: 200px;
height: 200px;
background: #e57676;
border: 1px solid #181515;
/*居中方法二:*/
/*margin-left: auto;*/
}
.container:last-child {
margin-left: auto;
}
</style>
</body>
</html>
左右两列 + 一个居中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper {
background: #f0f0f0;
height: 100vh;
display: flex;
}
.container1 {
width: 200px;
height: 200px;
background: #e57676;
border: 1px solid #181515;
}
.container2 {
width: 200px;
height: 200px;
background: #e57676;
border: 1px solid #181515;
}
.container3 {
width: 200px;
height: 200px;
background: #e57676;
border: 1px solid #181515;
margin: 0 auto;
}
.container4 {
width: 200px;
height: 200px;
background: #e57676;
border: 1px solid #181515;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="container1"></div>
<div class="container2"></div>
<div class="container3"></div>
<div class="container4"></div>
</div>
</body>
</html>
巧妙利用该属性还可以实现列表布局:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper {
background: #f0f0f0;
height: 100vh;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
.container1, .container2, .container3, .container4, .container5, .container6, .container7, .container8, .container9, .container10, .container11, .container12 {
width: 200px;
height: 200px;
box-sizing: border-box;
background: #e57676;
border: 1px solid #181515;
--n: 8;
--gap: calc((100% - 200px * var(--n)) / var(--n) / 2);
margin: 10px var(--gap);
}
</style>
</head>
<body>
<div class="wrapper">
<div class="container1"></div>
<div class="container2"></div>
<div class="container3"></div>
<div class="container4"></div>
<div class="container5"></div>
<div class="container6"></div>
<div class="container7"></div>
<div class="container8"></div>
<div class="container9"></div>
<div class="container10"></div>
<div class="container11"></div>
<div class="container12"></div>
</div>
</body>
</html>