引言
在当今的网页开发中,响应式设计和灵活的布局方式变得越来越重要。而Flex 弹性布局(Flexbox)作为一种强大的 CSS 技术,为我们提供了一种简单而灵活的方式来创建复杂的布局结构。与传统的浮动布局和定位相比,Flexbox 更加直观、易于理解,并且能够更好地适应不同尺寸的屏幕和设备。
我们可以先来看看,为了实现一面这个水平垂直居中效果,不同的布局方式是如何实现的。
<body>
<div class="parent">
<div class="child">子元素</div>
</div>
</body>
/* 公共样式 */
.parent {
width: 300px;
height: 300px;
background-color: orange;
}
.child {
width: 100px;
height: 100px;
background-color: skyblue;
}
1. 定位 + margin
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
2. 定位 + transform
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
3. flex
.parent {
display: flex;
justify-content: center;
align-items: center;
}
以上三种布局都能够实现元素的水平垂直居中,不难看出,flex布局是最简单的。
所以了解并学习flex布局对于前端学者来说是很有必要的。
一、Flex 布局简介
Flex 弹性布局(Flexbox)是一种用于网页布局的 CSS 技术,旨在使容器内的子元素能够自动调整大小和位置,以适应不同的屏幕尺寸和设备。与传统的布局技术相比,Flexbox 提供了更加灵活、简洁且强大的布局方式,使开发者能够更轻松地实现各种复杂的布局结构。
Flexbox 的核心思想是将容器内的子元素视为可伸缩的弹性盒子,可以根据需要自动调整其大小和位置,以填充可用空间。通过简单的 CSS 属性设置,开发者可以轻松地控制子元素的排列顺序、对齐方式以及相对大小的比例关系,而不需要依赖复杂的浮动和定位技术。
通过给父容器添加flex属性就能够开启弹性布局。子容器可以单独设置自身的排列方式,若果两者同时设置,以子容器的设置为准。
二、Flex 基础概念
flex的基础概念主要包含了容器与项目,主轴与交叉轴
2.1 容器与项目
2.1.1 Flex 容器:
- Flex 容器是应用了
display: flex;或display: inline-flex;属性的元素,也叫父容器。 - 这些属性告诉浏览器将容器内的子元素视为 Flex 项目,从而启用 Flexbox 布局模型。
- Flex 容器创建了一个新的布局上下文,影响其中的子元素的布局方式。
2.1.2 Flex 项目:
- Flex 容器内的直接子元素被称为 Flex 项目,也就是子容器(
item)。 - 这些项目根据 Flexbox 的规则在容器内排列和布局。
- Flex 项目的大小和位置可以根据 Flexbox 属性进行调整,以适应不同的布局需求。
2.2 主轴与交叉轴
2.2.1 主轴(Main Axis):
- 主轴是 Flex 容器的主要方向,决定 Flex 项目的排列方式。
- 默认情况下,主轴是水平方向(
row,x轴),但可以通过设置flex-direction属性来改变。 - Flex 项目沿着主轴排列,其大小和位置受到主轴方向的影响。
2.2.2 交叉轴(Cross Axis):
- 交叉轴是与主轴垂直的方向,用于控制 Flex 项目在垂直方向上的布局。
- 默认情况下,交叉轴是垂直方向(
column,y轴),但同样可以通过设置flex-direction属性进行更改。 - 交叉轴上的对齐方式由
align-items和align-self属性控制。
- 在 flex 布局中,是分为主轴和交叉轴两个方向,同样的叫法有 : 行和列、x 轴和y 轴,主轴和侧轴
- 主轴和交叉是会变化的,就看
flex-direction设置谁为主轴,剩下的就是交叉轴。而我们的子元素是跟着主轴来排列的
| flex-direction: 值 | 含义: |
|---|---|
row | 默认值,表示主轴从左到右,水平方向 |
row-reverse | 表示主轴从右到左,水平方向 |
column | 表示主轴从上到下,垂直方向 |
column-reverse | 表示主轴从下到上,垂直方向 |
三、主轴与交叉轴的设置
<div class="parent">
<div class="child item1">子元素1</div>
<div class="child item2">子元素2</div>
</div>
3.1 flex-direction: row
flex-direction: row 为默认属性,主轴沿着水平方向向右,元素从左向右排列。
3.3 flex-direction: row-reverse
主轴沿着水平方向向左,子元素从右向左排列
3.3 flex-direction: column
主轴垂直向下,元素从上向下排列
3.4 flex-direction: column-reverse
主轴垂直向下,元素从下向上排列
四、父容器常用属性
在父容器上的属性:
display: flex;或display: inline-flex;:定义元素为 Flex 容器。flex-direction:指定主轴方向,决定 Flex 项目的排列方向。flex-wrap:定义 Flex 项目在容器中是否换行。justify-content:控制 Flex 项目在主轴上的对齐方式。align-items:控制 Flex 项目在交叉轴上的对齐方式。align-content:控制多行 Flex 项目在交叉轴上的对齐方式。- 这些属性作用于父容器,用于控制容器内的 Flex 项目的布局和对齐方式。
<div class="parent">
<div class="child item1">子元素1</div>
<div class="child item2">子元素2</div>
<div class="child item3">子元素3</div>
</div>
父容器常用属性设置:
4.1 justify-content:主轴上的对齐方式
justify-content属性用于定义主轴上子元素的排列方式
4.1.1 flex-start
默认值,子元素向 Flex 容器的起始位置靠齐。
4.1.2 flex-end
子元素向 父 容器的结束位置靠齐。
4.1.3 center
子元素在 父 容器的中间位置居中对齐。
4.1.4 space-around
子元素会平均分布在 父 容器内,项目之间的间距相等,且首尾项目距离 父 容器的边缘的距离是其他子元素之间的一半。
4.1.5 space-between
子元素会平均分布在 父 容器内,首尾项目分别靠近 父 容器的起始和结束位置。
4.1.6 space-evenly
子元素会平均分布在 父 容器内,包括首尾项目和 父 容器的边缘之间的空间。
4.2 align-items:交叉轴上的对齐方式
align-items是用于控制 单行 子元素在交叉轴上的对齐方式。。以下默认主轴为水平方向向右,记住交叉轴是与主轴垂直哦,默认为垂直向下。
4.2.1 flex-start
默认值,子元素在交叉轴的起始位置对齐。
4.2.2 flex-end
子元素在交叉轴的结束位置对齐。
4.2.3 center
子元素在交叉轴的中间位置居中对齐,这里是y轴,y轴默认垂直向下。
4.2.4 stretch
子元素被拉伸以适应容器的高度或宽度。这是默认的行为,如果子元素没有设置高度或者宽度的话。
4.3 align-content: 交叉轴上多行子元素的对齐方式
align-content是应用于 父 容器的属性,用于控制 多行 子元素在交叉轴上的对齐方式。具体来说,当容器内有 多行 子元素时才会生效。因此需要在 父 容器中添加一个属性
flex-wrap: wrap;即当所有子元素的宽度超过父容器时,换行显示。
.parent {
display: flex;
flex-wrap: wrap; //换行显示
}
4.3.1 flex-start
默认值,多行子元素向 父 容器的起始位置靠齐。
4.3.2 flex-end
多行子元素向 父 容器的结束位置靠齐。
4.3.3 center
多行子元素在交叉轴的中间位置居中对齐,这里是y轴,y轴默认垂直向下。
4.3.4 space-around
多行子元素会平均分布在 父 容器内,行与行之间的间距相等,且首尾行距离 父 容器的边缘的距离是其他行之间距离的一半。
4.3.5 space-between
多行子元素目会平均分布在 父 容器内,首尾行分别靠近 父 容器的起始和结束位置。
4.3.6 stretch
默认行为,多行子元素会被拉伸以填充 父 容器的整个交叉轴。如果子元素具有固定的高度,则会被拉伸至容器高度;否则会根据子元素的最大高度进行拉伸。
4.4 flex-wrap: 是否换行
flex-wrap是用于控制子元素是否换行。具体来说,它指定了 父 容器内的子元素是否在一行上排列,或者是否允许它们换行到下一行。
4.4.1 nowrap
默认值,不换行,尽可能地排在一行上。
4.4.2 wrap
自动换行到下一行,以适应 父 容器的宽度。
五、子容器常用属性
在子容器上的属性:
order:定义 Flex 项目的排列顺序。flex-grow:指定 Flex 项目在空间分配时的放大比例。flex-shrink:指定 Flex 项目在空间不足时的收缩比例。flex-basis:定义 Flex 项目在主轴上的初始大小。flex:flex-grow,flex-shrink, 和flex-basis的缩写属性。align-self:覆盖父容器的align-items属性,单独控制某个 Flex 项目在交叉轴上的对
子容器常用属性设置:
5.1 order 属性
作用:定义子元素的排列顺序,决定了子元素在 父 容器中的显示顺序。数值越小,越靠前。
默认值:0。
.item2 {
order: -1; //默认值为0,那么给第二个子元素设为-1,它就跑到第一的位置了
}
5.2 flex 属性
flex 属性定义子元素分配剩余空间,用flex来表示占多少份数。
默认值:0
现在父容器宽度为400px,子元素1和子元素3宽度为100px,剩余宽度给子元素2
.item2 {
flex: 1; //默认值为0
}
5.3 align-self 属性
align-self:覆盖父容器的align-items属性,单独控制某个子元素在交叉轴上的对齐方式。
5.3.1 flex-start
.parent{
display: flex;
align-items: center; //父容器我们设置子元素交叉轴上居中
}
.item1 {
align-self: flex-start; //子元素1我们单独设置起始端对齐
}
5.3.2 flex-end
.parent{
display: flex;
align-items: flex-start; //父容器我们设置子元素交叉轴上起始端对齐
}
.item1 {
align-self: flex-end; //子元素1我们单独设置末端对齐
}
5.3.3 center
.parent{
display: flex;
align-items: flex-start; //父容器我们设置子元素交叉轴上起始端对齐
}
.item1 {
align-self: center; //子元素1我们单独设置交叉轴上居中
}
5.3.4 stretch
.parent{
display: flex;
align-items: flex-start; //父容器我们设置子元素交叉轴上起始端对齐
}
.item1 {
align-self: strtch; //子元素1我们单独设置交叉轴上拉伸
}
item1没有设置高度
六、实例
实现一个菜单功能,有新增和删除功能,在进行菜单整体布局时,我们会用到flex弹性布局。
//将todoData中的数据渲染出来
function render() {
var str = '';
//遍历
todoData.forEach(function (item) {
str += `<li class="item">
<div class="flex">
<input type="checkbox" class="item-check">
<p class="item-content">${item.title}</p>
<span class="close" data-action="remove" data-id="${item.id}">x</span>
</div>
</li>`
})
todoList.innerHTML = str
}
todoData.forEach(function (item) { ... }:
- 使用
forEach方法遍历todoData数组中的每个待办事项对象。 - 对于每个待办事项对象,执行一个匿名函数,参数
item是当前正在处理的待办事项对象。
str += <li class="item"> ... </li>:
- 在循环中,将每个待办事项对象转换为 HTML 列表项,并追加到
str变量中。 - 每个列表项包含一个类名为
item的<li>元素,其中包含一个 Flex 容器 div,包含一个复选框、一个文本段落和一个关闭按钮。 - 关闭按钮通过
data-action="remove"和data-id="${item.id}"属性附加了删除待办事项所需的动作和标识符。
todoList.innerHTML = str;:
- 在循环结束后,将包含所有待办事项列表项的 HTML 字符串赋值给
todoList元素的innerHTML属性。 - 这样就将渲染好的待办事项列表插入到页面的相应位置中。
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: 500px;
height: 500px;
margin-top:300px;
/* border: 1px solid black; */
}
.title {
text-align: center;
margin: 10px;
}
.input-group {
display: flex;
}
.label {
padding: 5px 10px 5px 10px; /* 上右下左 */
}
.btn {
padding: 5px 10px;
margin-left: 10px;
}
.content {
flex: 1;
}
.item:first-child {
margin-top: 20px;
}
.item {
border-bottom: 1px solid #eee;
}
.flex {
display: flex;
width: 90%;
margin: 0 auto;
align-items: center;
}
.item-check {
margin-right: 20px;
}
.item-content {
flex: 1;
}
.close {
width: 30px;
height: 30px;
border: 1px solid gray;
font-style: 20px;
text-align: center;
border-radius: 10px;
cursor: pointer;
}
.input-group { display: flex; }:
- 这将输入框组内的元素设置为 Flex 布局,使其在水平方向上排列。
.flex { display: flex; ... }:
- 这将具有
flex类的元素设置为 Flex 布局,使其内部元素在水平方向上居中对齐。 width: 90%;设置了该元素的宽度为父容器宽度的 90%。margin: 0 auto;让该元素在水平方向上居中对齐。align-items: center;设置了元素内部元素在交叉轴上的居中对齐。
.item-content { flex: 1; }:
- 这将具有
item-content类的元素设置为 Flex 布局,使其在主轴上占据剩余空间。
最后
Flex 布局是一种强大的 CSS 布局技术,用于创建灵活的、响应式的布局。通过简单的属性设置,可以实现元素的自动调整大小、对齐和分布,适应不同的屏幕尺寸和设备。核心概念包括弹性容器和弹性项目,通过控制主轴和交叉轴的方向、对齐方式以及弹性增长和收缩,实现各种布局需求。Flex 布局简化了布局代码,提高了开发效率,是构建现代网页布局的首选技术之一。
希望能够帮助你了解flex弹性布局,未来继续学习更加灵活的布局方式,我们拭目以待。