flex布局
Flexbox (弹性盒子)布局是在 2017 年 10 月的 W3C 候选建议添加的一种布局方式,旨在提供一种更有效的方式来在容器与元素之间布局、对齐、分配空间,即使元素的大小未知、甚至是动态生成。
弹性盒子布局背后的主要思想是使容器能够改变其元素的宽度、高度(和顺序),以便更好的填充可用空间(主要是为了适应所有的显示设备与屏幕尺寸)。
更重要的是,与常规布局(垂直布局与水平布局)相反,弹性盒子布局与方向无关,虽然这些技术适用于页面,但是对于支撑大型复杂的页面来说它们缺乏灵活性(特别是在布局方向更改、调整大小、拉伸、缩小等方面)。
基础知识和术语
由于 flexbox 是一个完整的模块,而不是一个单一的属性,它涉及很多事情,包括它的整套属性。其中一些应该在容器(父元素,称为“flex 容器”)上设置,而其他的则应该在子元素(称为“flex items”)上设置。
如果“常规”布局同时基于块流和内联流方向,则挠性布局基于“柔性流方向”。请从规范中查看此图,解释 flex 布局背后的主要思想。
项目将按照 main axis(主轴、十字轴)从左(main-star)到右(main-end)进行布局,或者是按照 cross axis(交叉轴)从上(cross-start)到下(cross-end)布局
注意
flexbox 没有横轴与竖轴的概念,因为主轴与交叉轴是可以变化的。
- main axis(主轴):flexbox 的主轴是项目的布局核心。它不一定是水平的,主要取决于 flex-direction 属性(见下文)
- main-start | main-end:弹性项目放置在容器内,从开始到结束的位置。
- main size:弹性项的宽度或高度(以主维度中的为准)是项目的主要尺寸。弹性项的主尺寸属性是“宽度”或“高度”属性,以主维度中的个体为准。
- cross axis:垂直于主轴的轴称为交叉轴。它的方向取决于主轴方向。
- cross-start | cross-end:弹性项目放置在容器内,从开始到结束的位置。
- cross size:弹性项的宽度或高度(以十字尺寸中的较大者为准)是项的交叉大小。交叉大小属性是交叉维度中的“宽度”或“高度”中的任何一个。
父项常见属性
想要使用 flexbox 布局,首先需要开启 flex 布局模式
.container {
display: flex; /* or inline-flex */
}
flex-direction 主轴方向
使用 flex-direction 属性可以设置主轴,从而确定 flex 子元素的放置方向。flexbox 是单向布局概念,将 flexbox 中的内容在水平列或者垂直列进行布局
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row(默认值):从左到右是 ltr,从右到左是 rtl。
- row-reverse:从右到左是 ltr,从左到右是 rtl。
- column:与上面相同,但是 row 变为从上到下
- column-reverse:与相同 row-reverse ,但从下到上
1、row(默认)
默认方向是行。这意味着主轴是水平的,而横轴是垂直的。这也意味着主轴从左侧开始,而横轴从顶部开始。
.flex-container {
display: flex;
flex-direction: row;
}
2、row-reverse
与 row 类似,我们有 row-reverse。该方向不会交换主轴/交叉轴,但会交换主轴开始的位置。主轴现在从右边开始,而横轴没有改变,仍然从顶部开始。
.flex-container {
display: flex;
flex-direction: row-reverse;
}
3、column
列方向完全交换了我们的轴,所以现在主轴是垂直的,横轴是水平的。
.flex-container {
display: flex;
flex-direction: column;
}
4、column-reverse
column-reverse 方向与 column 基本相同,但它反转了主轴的方向,因此现在项目从容器的底部开始。
.flex-container {
display: flex;
flex-direction: column-reverse;
}
flex-wrap
默认情况下,弹性项目将全部尝试适合一行。您可以更改此设置,并允许使用此属性根据需要包装项。
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap (默认值):所有子元素都将在一行上
12345678wrap :子元素将从上到下换行到多行。
12345678wrap-reverse :子元素将从下到上换行到多行。
12345678
justify-content 对齐方式
这个属性定义了子元素沿主轴的对齐方式。当一行上所有的子元素都不没有占满整个空间时,有助于分配额外的剩余空间。如果子元素已经占满父元素的宽度并溢出到下一行,可以对子元素的对齐方式进行控制
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
- flex-start(默认值):将元素从主轴的开始处进行布局。
- flex-end:将元素从主轴的末尾处进行布局。
- center:子元素居中显示
- space-between: 均分分布在一行,第一项从最左边开始,最后一项贴齐右边。
- space-around:均匀分布在一行中,每个子元素左右两边的间距相等。
- space-evenly: 每个子元素直接的距离相等。
justify-content 演示代码
对于下方所有示例,我们将假设 flex-items 的宽度为 20%。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>flex-direction</title>
<style>
.flex-container {
display: flex;
border: 1px dashed black;
justify-content: flex-start;
}
.flex-item {
width: 20%;
height: 10rem;
background-color: deepskyblue;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
</body>
</html>
1、flex-start(默认)
将所有项目放置在主轴的起点,默认情况下是轴的左侧。这也是 justify-content 的默认行为。
css.flex-container { display: flex; justify-content: flex-start; }
1232、flex-end
将所有项目放置在主轴的末端,默认情况下是轴的右侧。
css.flex-container { display: flex; justify-content: flex-end; }
1233、center
将所有项目放置在主轴的中心。这是在 CSS 中居中元素的最简单方法之一。
css.flex-container { display: flex; justify-content: center; }
1234、space-between
这会占用容器内的所有额外空间,并将其均匀分布在每个元素之间,以在填充整个容器的同时将它们彼此间隔得尽可能远。
css.flex-container { display: flex; justify-content: space-between; }
1235、space-around
这与 space-between 非常相似,但它也在容器外部和第一个/最后一个元素之间增加了空间。容器外部和第一个/最后一个元素之间的空间量正好是元素之间空间量的一半。
css.flex-container { display: flex; justify-content: space-around; }
123
总结
属性名 | 效果 |
---|---|
flex-start | 默认值从头部开始如果主轴是 x 轴,则从左到右 |
flex-end | 从尾部开始排列 |
center | 在主轴居中对齐(如果主轴是 x 轴则水平居中) |
space-around | 平分剩余空间 |
space-between | 先两边贴边再平分剩余空间(重要) |
align-items 子元素项
align-items 这定义了弹性项目沿当前行的交叉轴布局方式的默认行为。将其 justify-content 视为十字轴(垂直于主轴)的版本。
该属性是控制子项在侧轴(默认是 y
轴)上的排列方式 在子项为单项(单行)的时候使用
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
- stretch(默认值):拉伸以填充容器(仍遵循最小宽度/最大宽度)
- flex-start / start / self-start:项目放置在十字轴的开头。这些之间的区别是微妙的。
- flex-end / end / self-end:末端对齐
- center:在十字轴上居中
- baseline :项目对齐,例如其基线对齐
对于下方这些示例,我们将假设 flex-items 的宽度均为 20%,但元素的高度都不同。
<style>
.flex-container {display: flex;border: 1px dashed black;}
.flex-container .item {width: 100px;background-color: deepskyblue;border: 1px solid;}
.flex-container .item:nth-child(0) {height: 60px;}
.flex-container .item:nth-child(1) {height: 80px;}
.flex-container .item:nth-child(2) {height: 100px;}
</style>
<div class="flex-container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
1、flex-start
这与 justify-content 的 flex-start 的工作原理相同,但默认情况下将从交叉轴的顶部开始。
css.flex-container { display: flex; align-items: flex-start; }
1232、flex-end
这与 justify-content 的 flex-end 的工作原理相同,但默认情况下将从交叉轴的底部开始。
css.flex-container { display: flex; align-items: flex-end; }
1233、center
这与 justify-content 的
center
相同,但将基于交叉轴居中。css.flex-container { display: flex; align-items: center; }
1234、stretch(默认)
css.flex-container { display: flex; align-items: stretch; }
123
属性名 | 效果 |
---|---|
flex-start | 默认值从头部开始如果主轴是 x 轴,则从左到右 |
flex-end | 从尾部开始排列 |
center | 在主轴居中对齐(如果主轴是 x 轴则水平居中) |
stretch | 拉伸 |
高级 Flexbox 属性
目前分享的内容已经涵盖了 flexbox 的所有基础和进阶属性,现在我想涵盖一些高级/小众的 flexbox 属性。
添加间隙
到目前为止我们还没有涉及的一件事是能够在 flexbox 容器中的元素之间添加间隙。你可以尝试使用margin/padding来执行此操作,但更简单的方法是使用 gap 属性。此属性将根据我们传递给 gap 的值在每个项目之间添加空间。
.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}
正如你所看到的,我们上面的每个项目之间都有 10px 的间隙。这种差距也适用于多行 flex 容器。
附录
- flexbox 完全入门指引手册: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
- flex 小游戏:https://flexboxfroggy.com/