这篇文章将学习 CSS 的 Flex 布局和 Grid 布局。
Flex 布局
Flex(Flexible Box)布局,也称为 弹性盒子布局,是 CSS3 中常用的现代布局模型之一。采用 Flex 布局的元素,称为 Flex 容器,它的所有直系子元素自动成为容器成员,称为 Flex 项目(flex item)。Flex 布局 是轴线布局,只能指定 项目 针对轴线的位置,它特别适用于一维布局(行或列)。
轴线
Flexbox 的强大之处在于它不依赖于传统的 width 和 height 属性,而是依赖于主轴和交叉轴的动态概念。在 Flex 容器中,默认存在两条相互垂直的轴:
- 主轴(Main Axis):Flex 项目主要沿着这个轴线排列
- 交叉轴(Cross Axis):与主轴垂直的轴线
Flex 布局最重要的一点:主轴和交叉轴是相对的,会随着 flex-direction 的变化而互换:
| flex-direction | 主轴方向 | 交叉轴方向 |
|---|---|---|
| row(默认)/row-reverse | 水平方向 | 垂直方向 |
| column/column-reverse | 垂直方向 | 水平方向 |
- row(默认值):主轴为水平方向,从左到右
- row-reverse:主轴为水平方向,从右到左
- column:主轴为垂直方向,从上到下
- column-reverse:主轴为垂直方向,从下到上
由于主轴和交叉轴的方向是动态的,因此又有了如下概念,这些概念始终是相对于 Flex 容器的,而不是固定的屏幕方向(如上、下、左、右):
- Main Start:主轴的开始位置(与边框的交叉点)
- Main End:主轴的结束位置
- Cross Start:交叉轴的开始位置
- Cross End:交叉轴的结束位置
项目默认沿主轴排列。单个项目占据的主轴空间叫做 main size,占据的交叉轴空间叫做 cross size。例如在 display: flex 的布局下,默认的主轴方向是水平方向(flex-direction: row),也就是说,子元素会沿着水平排列:
- 如果有 3 个元素,宽度分别为 100px、200px 和 150px,高度分别为 50px、70px 和 60px
- 那么它们沿着主轴的空间分别是 100px、200px 和 150px
- 那么它们的交叉轴空间分别是 50px、70px 和 60px
下图展示默认使用 flex-direction: row 时这些概念的示意图:
对齐属性
justify-content 是 Flex 布局中一个极其重要的属性,它定义了 Flex 项目在主轴 (Main Axis) 上的对齐方式和空间分布:
flex-start(默认):靠主轴起点对齐 (Main Start),项目都集中在主轴的起始端
1 | |██ ██ ██ | |
flex-end:靠主轴终点对齐 (Main End),项目都集中在主轴的末端
1 | | ██ ██ ██| |
center:居中对齐,项目集中在主轴的中央
1 | | ██ ██ ██ | |
space-between:两端对齐,项目之间间距相等
1 | |██ ██ ██| |
space-around:每个项目两侧都有空间,中间间距是边缘的 2 倍
1 | | ██ ██ ██ | |
space-evenly:所有间距完全相等,包括边缘和中间
1 | | ██ ██ ██ | |
align-items 则控制项目在 交叉轴 (Cross Axis) 上的对齐,align-items 属性设置在 Flex 容器 上,并且它对单行 Flex 项目的对齐方式起作用。
- stretch (默认):拉伸,如果项目未设置高度,或高度设为
auto,项目将拉伸至占满容器的整个交叉轴高度(长度) - flex-start:靠交叉轴起点(Cross Start)对齐
- flex-end:靠交叉轴终点(Cross End)对齐
- center:在交叉轴方向居中对齐
- baseline:基线对齐,项目以它们的内容基线对齐
下面的示例,展示了 justify-content 和 align-items 属性不同组合下的布局效果:
1 |
|
align-content 属性则专门用于处理 多行 (Multi-line) Flex 布局,用于控制多根轴线在交叉轴方向上整体的对齐和空间分布。例如当 flex-direction: row(主轴水平)时,align-content 控制的是多行项目在垂直方向上的分布:
- stretch (默认):拉伸,轴线占满整个交叉轴
- flex-start:靠交叉轴起点对齐
- flex-end:靠交叉轴终点对齐
- center:在交叉轴方向居中对齐
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布
- space-around:
轴线间隔比轴线与边框的间隔大一倍 - space-evenly:所有间距完全相等
flex 项目属性
以上讨论的都是 Flex 容器的属性,接下来列举和总结设置在 Flex 项目 上的六个主要属性。这些属性控制单个项目在容器中的行为、大小和顺序。
| 属性 | 作用 | 默认值 | 详细解释 |
|---|---|---|---|
| order | 排列顺序 | 0 | 定义项目的排列顺序。数值越小,项目越靠前,可以是负数。 |
| flex-grow | 放大比例 | 0 | 定义当容器有剩余空间时,项目将占据的放大比例。0 表示不放大。 |
| flex-shrink | 缩小比例 | 1 | 定义当容器空间不足时,项目将收缩的比例。0 表示不缩小。 |
| flex-basis | 主轴基准值 | auto | 定义项目在分配剩余空间之前,在主轴上占据的初始尺寸。 |
| flex | 简写属性 | 0 1 auto | 是 flex-grow、flex-shrink 和 flex-basis 的简写。 |
| align-self | 单项对齐 | auto | 允许单个项目有不同于容器 align-items 的对齐方式,覆盖容器的设置。 |
Grid 布局
Grid 布局(网格布局)是 CSS 中最强大的二维布局系统。它允许您同时在行 (Rows) 和 列 (Columns) 两个维度上控制元素的排列和定位,非常适合创建复杂的网页结构和响应式设计。与 Flexbox(一维布局,只能沿着主轴或交叉轴排列)相比,Grid 布局更擅长将整个页面划分成主要区域。
网格布局中,存在如下基本概念:
网格容器(Grid Container):指设置了display: grid或display: inline-grid的元素。它是整个网格系统的父元素网格项目(Grid Item)则是网格容器的直接子元素,它们将在网格中进行定位和布局,网格线(Grid Line):划分网格的水平和垂直分界线。它们从 1 开始编号网格轨道(Grid Track):两条相邻网格线之间的空间,即网格的行或列网格单元(Grid Cell:由两条行网格线和两条列网格线围成的最小区域(类似表格的单元格)网格区域(Grid Area):由任意数量的网格单元组成的矩形区域,可用于放置一个网格项目
容器属性
首先介绍网格容器的相关属性。display: grid 将元素设置为网格容器:
1 | .container { display: grid; } |
容器指定了网格布局以后,接着就要划分行和列。grid-template-rows:定义行的数量和每行的高度,对于如下配置
1 | grid-template-rows: 100px auto 1fr; |
- 第一行高 100px,第二行高度自适应内容,第三行占据剩余空间
fr单位: 代表分数 (Fraction)。它用于按比例分配网格容器中的可用空间,例如,1fr 2fr代表后者是前者的 2 倍
grid-template-columns 定义列的数量和每列的宽度:
1 | grid-template-columns: repeat(3, 1fr); |
- 创建 3 列,每列平均分配剩余空间
grid-template-areas 通过名称来定义网格区域,简化布局:
1 | grid-template-areas: "header header header" "sidebar main main"; |
- 将容器划分成三个列,两行,并命名了区域
需要注意,区域的命名会影响到网格线:
- 每个区域的起始网格线,会自动命名为
区域名-start,终止网格线自动命名为区域名-end
grid-row-gap 和 grid-column-gap 设置网格单元之间的行间距和列间距。grid-gap 属性是 grid-column-gap 和 grid-row-gap 的合并简写形式。
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。grid-auto-flow 属性决定了它们是按行填充还是按列填充,以及是否允许项目跨越多个单元格。
row (默认值):按行填充,项目从网格的第一行开始,依次填充可用的列。当一行被填满后,布局会移动到下一行column:按列填充,项目从网格的第一列开始,依次填充可用的行。当一列被填满后,布局会移动到下一列dense:密集填充,网格算法会尝试回填前面留下的任何小空隙。它会向前查找,找到一个适合当前项目尺寸的空位,即使这个空位在顺序上比当前项目靠前。row和column都可以与dense关键字结合使用,以优化空间利用
justify-items 属性设置单元格内容的水平位置(左中右),align-items 属性设置单元格内容的垂直位置(上中下),他们的取值可以是。
- start:对齐单元格的起始边缘
- end:对齐单元格的结束边缘
- center:单元格内部居中
- stretch:拉伸,占满单元格的整个宽度(默认值)
place-items 属性是 align-items 属性和 justify-items 属性的合并简写形式。
justify-content 属性是整个内容区域在容器里面的水平位置(左中右),align-content 属性是整个内容区域的垂直位置(上中下)。
项目属性
接下来介绍 Grid 布局中应用于网格项目 (Grid Item) 的主要属性,这些属性控制着单个项目在网格容器内的具体位置、大小和对齐方式。
- grid-column-start:定义项目在垂直网格线上开始的位置(左边界)。
- grid-column-end:定义项目在垂直网格线上结束的位置(右边界)
- grid-row-start:定义项目在水平网格线上开始的位置(上边界)。
- grid-row-end:定义项目在水平网格线上结束的位置(下边界)。
- grid-column:
grid-column-start和grid-column-end的合并简写形式 - grid-row:
grid-row-start和grid-row-end的合并简写形式 - grid-area:指定项目放在哪一个区域
- justify-self:属性设置单元格内容的水平位置(左中右),跟
justify-items属性的用法完全一致,但只作用于单个项目 - align-self:属性设置单元格内容的垂直位置(上中下),跟
align-items属性的用法完全一致,也是只作用于单个项目 - z-index:控制网格项目的堆叠顺序。当项目发生重叠时,
z-index值更高的项目会显示在更前面
简单示例
如下是 Grid 布局的一个简单示例:
1 |
|