前言
在《前端必备CSS之位置篇(文档流、定位与浮动)》这篇文章中,我们回顾了在弹性布局和Grid布局问世之前,占据主导地位的文档流、定位与浮动,而更具灵活性的弹性(Flex)布局和Grid布局现在已经几乎取代了浮动(float)的地位。接下来,我将带你一套通关其中的弹性布局,掌握现代CSS布局的半壁江山。
一、什么是弹性布局?
定义
弹性布局(Flexible Box Layout,简称 Flex 布局)是 CSS3 引入的一种一维布局模型,专门用于解决容器内元素的对齐、分布和自适应问题。它通过display: flex或display: inline-flex将容器设置为 “弹性容器”,其内部子元素成为 “弹性项目”,并通过容器和项目的属性控制项目的排列规则。
- 注意:
- 只有弹性容器的直接子元素才会自动成为弹性项目,孙子元素不直接受影响,它属于另一个层级。
- 它们的布局默认由正常的文档流(或其他布局方式,如自身的 flex 设置)控制,与外层弹性容器的 flex 属性无关(除非将孙子元素所在的弹性项目设置为新的弹性容器)。
- 核心概念:
- 弹性容器(Flex Container) :设置
display: flex(块级弹性容器) 或display: inline-flex(行内级弹性容器) 的父元素。 - 弹性项目(Flex Item) :弹性容器的直接子元素(孙子元素不直接受影响)。
- 主轴(Main Axis) :项目默认沿主轴排列(方向由
flex-direction决定)。 - 交叉轴(Cross Axis) :垂直于主轴的轴线(方向由主轴决定)。
- 弹性容器(Flex Container) :设置
弹性布局示图
弹性布局各部分情况如下图所示。
二、弹性布局属性
弹性布局的属性分为弹性容器属性和弹性项目属性,分别掌控弹性容器和弹性项目的显示效果。下面我们将分别介绍它们。
- 弹性容器核心属性:
flex-direction:决定主轴方向(项目排列方向)flex-wrap:控制项目是否换行flex-flow:flex-direction+flex-wrap的简写justify-content:控制项目在主轴上的对齐方式align-items:控制项目在交叉轴上的对齐方式(单行 / 单列时)align-content:控制多根轴线在交叉轴上的对齐方式(多行 / 多列时)
- 弹性项目核心属性:
flex-grow:项目的扩展比例(主轴方向剩余空间分配)flex-shrink:项目的收缩比例(主轴方向空间不足时收缩)flex-basis:项目在主轴上的初始尺寸(默认值auto)flex:flex-grow+flex-shrink+flex-basis的简写order:控制项目的排列顺序align-self:单个项目在交叉轴上的对齐方式(覆盖容器align-items)
(一)弹性容器属性
容器属性用于控制项目的整体排列规则,它有六个核心属性,如下所示。
1. flex-direction
flex-direction决定主轴方向(容器中的项目排列方向)。
-
核心值:
row(默认):主轴水平,项目从左到右排列。row-reverse:主轴水平,项目从右到左排列。column:主轴垂直,项目从上到下排列。column-reverse:主轴垂直,项目从下到上排列。
-
示图:
- 示例代码:
2. flex-wrap
flex-wrap控制项目是否换行,否则默认情况下,就算容器内的弹性项目宽度之和超过了容器宽度,也不会进行换行,而是会被容器自动压缩在主轴上面,排成一行。
-
核心值:
nowrap(默认):不换行,项目可能被挤压。wrap:换行,超出部分向下换行(交叉轴方向延伸)。wrap-reverse:换行,超出部分向上换行。
-
示图:
- 示例代码:
3. flex-flow
flex-flow是flex-direction + flex-wrap 的简写,相当于同时声明了上面的 flex-direction 以及flex-wrap 两个属性。
- 语法:
flex-flow: <flex-direction> <flex-wrap>(默认row nowrap)。 - 示例:
- 示图:
- 示例代码:
- 示图:
4. justify-content
justify-content控制项目在主轴上的对齐方式。
- 核心值:
flex-start(默认):左对齐。flex-end:右对齐。center:居中对齐。space-between:两端对齐,项目间距相等(首尾项目贴边)。space-around:项目两侧间距相等(首尾项目距边缘为中间间距的一半)。space-evenly:项目间距和首尾距边缘完全相等。
- 示例(以主轴水平为例):
- 示图:
- 示例代码:
- 示图:
5. align-items
align-items控制项目在交叉轴上的对齐方式(单行 / 单列时)。
- 核心值:
stretch(默认):项目高度拉伸至与容器等高。flex-start:顶端对齐。flex-end:底端对齐。center:居中对齐。baseline:项目基线(文字底部)对齐。- 示例(以交叉轴垂直为例):
- 示图:
- 示例代码:
- 示图:
6. align-content
align-content控制多根轴线在交叉轴上的对齐方式(多行 / 多列时)。
- 注意:仅当项目换行(
flex-wrap: wrap)且产生多根轴线时有效。 - 核心值:
stretch(默认):轴线拉伸至填满容器(前提是子元素没有设置固定宽或者高,比如如果手动设置了子元素的高50px,就会覆盖stretch,子元素按照手动设置的尺寸显示)。flex-start:所有轴线顶端对齐。flex-end:所有轴线底端对齐。center:所有轴线居中对齐。space-between:轴线两端对齐,轴线间距相等。space-around:轴线两侧间距相等。
- 示例:
- 示图:
- 示例代码:
- 示图:
(二)弹性项目属性
项目属性用于控制单个项目的表现,和弹性容器一样,它也有六个核心属性,如下所示。
1. flex-grow
flex-grow负责控制项目的扩展比例(主轴方向剩余空间分配),也就是我们常用的按比例分配,但是比我们手动输入百分比要准确且方便的多,毕竟有时候得到的小数是除不尽的(比如1/3,我们如果手动输入33.3%还是会有误差,但是设置成1:1:1就不会了)。
- 取值规则: 默认为0,即为不进行扩展,要求输入值必须是非负数字。
- 分配规则:分配完项目空间之后,容器内剩余空间按各项目
flex-grow设置的比例分配。 - 示例:下面是一个
1:1:1的分配示例,容器宽度800px,而项目宽度设定为100px,分配完设定的项目宽度后,剩余的500px被按照比例分配给各项目。-
效果示图:
-
item1扩展示图: -
item2扩展示图: -
item3扩展示图: -
扩展逻辑:容器宽度为
800px,内有三个宽度为100px的弹性项目,分配完项目的空间之后,容器内还剩下500px的空间用于分配扩展空间,由于比例为1:1:1,所以每个弹性项目各分到三分之一,即500px / 3≈166.67px -
示例代码:
-
2. flex-shrink
flex-shrink负责控制项目的收缩比例(主轴方向空间不足时收缩)。这个我们在前面未开启换行时,就经常碰到这个情况,容器内的项目被自动压缩至一行。
- 取值规则:默认为1,即为允许收缩(与
flex-grow相反),要求输入值必须是非负数字。 - 搜索规则:空间不足时,项目按
flex-shrink比例收缩(0 表示不收缩)。 - 示例: 现在有一个宽度为
800px的弹性容器,内有三个宽度为300px的弹性项目,很明显容器空间不足,将会进行收缩。-
效果示图:
-
item1收缩示图:
-
item2不收缩示图:
-
item3收缩示图:
-
收缩逻辑:由于容器只有
800px,三个弹性项目初始设置宽度都有300px,所以有100px的空间缺口,需要压缩容器内的弹性项目,把这要压缩的100px按收缩比例分配给item1以及item3(item2的flex-shrink为0,不参与收缩)。- 由
item1以及item3的原width减去分配到的收缩空间,得到最终显示的宽度。 - 其中
item11份,item32份,item1收缩100px/3≈33.33px,item3收缩100px * 2/3≈66.67px。
- 由
-
示例代码:
-
3. flex-basis
flex-basis负责控制项目在主轴上的初始尺寸(默认值 auto),其优先级比width或者height高。
-
作用规则:定义项目未扩展 / 收缩前的基础尺寸(优先级高于
width/height,即会覆盖width或者height的设置)。- 具体覆盖谁要看主轴方向:
- 主轴方向为水平:覆盖
width。 - 主轴方向垂直:覆盖
height。
- 主轴方向为水平:覆盖
- 具体覆盖谁要看主轴方向:
-
取值规则:默认为
auto(由内容或width决定),也可以设置为具体尺寸(如100px、50%,将会覆盖width或是height),同样必须为非负数。 -
示例:设置一个容器宽度为
300px,内有三个弹性项目。-
效果示图:
-
item1示图: -
item2示图: -
item3示图:
- 示例代码:
-
4. flex
flex 是 flex-grow + flex-shrink + flex-basis 的简写,相当于同时声明了这三个属性。
- 语法:
flex: <flex-grow> <flex-shrink> <flex-basis>(默认0 1 auto)。 - 常用简写:
flex还能再进一步简写。flex: auto:等价于1 1 auto(允许扩展和收缩,基础尺寸自动)。flex: none:等价于0 0 auto(不扩展不收缩,基础尺寸自动)。flex: 1:等价于1 1 0%(常用作 “等分空间”)。
- 示例(等分空间):以我们常用的 “等分空间” 为例。
-
为什么设置
basis: 0%?:因为等分空间的重点就在于消除自身内容尺寸的干扰,将自身初始尺寸占比设为0%,使得分配空间时,能够完全按照比例分配全部可用空间。 -
示图:容器被等分为三部分等宽的空间。
-
示例代码:
-
5. order
order控制项目的排列顺序,与优先级的设置相反,order的值越小,排序越靠前。
- 取值规则:默认为0,必须为整数(可以为负值)。
- 示例:
- 示图:
- 示例代码:
- 示图:
6. align-self
align-self负责控制单个项目在交叉轴上的对齐方式(手动设置之后会覆盖容器 align-items)。
- 取值规则:取值规则和容器属性
align-item一样,但是默认为auto(表示继承容器的align-items),手动设置之后会覆盖容器align-items。 - 核心值:和容器
align-items一样,但是默认值为auto。auto(默认):继承容器的align-items值。stretch:项目高度拉伸至与容器等高。flex-start:顶端对齐。flex-end:底端对齐。center:居中对齐。baseline:项目基线(文字底部)对齐。
- 示例:
-
示图:
-
示例代码:
-
三、弹性布局实战篇
弹性布局需要结合实战来理解,所以我将列举一些常见的弹性布局。
1. 四合院布局(语义化)
适用范围最广的四合院布局,并且通常会结合HTML5的语义化标签,即为一个Header、左右共两个Aside、一个Main、一个Footer。
-
示图:
-
示例:
-
效果图:
-
示例代码:
-
2. 导航栏布局
还有无论何时都居中显示的顶部导航栏布局。
-
示图:
-
示例代码:
3. 基于弹性布局的卡片网格布局
网站中的信息很多都是以卡片的格式网格状展示,所以这个也是个常用的布局方式。
-
示图:
-
示例代码:
4. 单侧边栏
很多网站都是单侧边栏(比如左边显示目录),右边主内容区,相当于简化了四合院布局。
-
示图:
-
示例代码:
结语
弹性布局(Flexbox)作为 CSS3 的里程碑式特性,彻底改变了前端布局的开发模式。它通过简洁的 API 解决了传统布局中 “垂直居中”、“等高列” 等经典难题,让响应式设计变得触手可及。随着浏览器兼容性的全面提升,弹性布局已成为前端工程师的必备技能,而浮动已成弃子。
这篇文章只能算是 CSS 布局的半壁江山,因为还有一半江山在 Grid 布局那里,它涉及到更复杂的二维排版,而弹性布局是一维排版,我们下次再讲 Grid 布局,精彩仍在继续哦。
如果这篇文章有帮助到你,不胜荣幸;如果文章有错误或者缺漏,请在评论区指出,大家一起进步,谢谢🙏。