网格布局 | 自在学网格布局
在网页设计的发展历程中,一直存在着一个有趣的现象:开发者们总是想方设法地使用现有技术来实现复杂的布局效果。早期的网页设计师们曾经借助浮动和定位技术来搭建页面框架,但这些方法往往伴随着脆弱的布局结构和难以维护的代码。
CSS网格布局的出现就像是为网页布局领域注入了一股清新的空气。它不仅仅是另一种布局技术,更像是一位经验丰富的建筑师,为我们提供了一套完整而强大的布局工具集。通过网格布局,我们能够以前所未有的精确度和灵活性来组织页面元素。

实验室
创建网格容器
网格布局的一切都始于一个简单的CSS声明。当我们为一个元素应用display: grid时,这个元素就摇身一变成为了网格容器。这个看似简单的变化却在背后建立了一个全新的格式化上下文。
网格容器可以是块级网格,也可以是行内网格。通过设置display: grid,我们创建的是一个块级网格容器,它会占据可用的水平空间。而display: inline-grid则创建行内网格容器,它只占据内容所需的宽度。
<!DOCTYPE html>
<html>
<head>
<style>
.grid-container {
display: grid;
background-color: #f0f0f0;
padding: 10px;
gap: 10px;
}
.grid-item {
background-color
有趣的是,网格容器与传统的块容器有着显著的区别。网格容器不会让浮动元素从旁边溜走,也不会让子元素的边距发生折叠。这些特性确保了网格布局的稳定性和可预测性。
网格布局的术语
要深入理解网格布局,我们需要掌握一套专门的术语体系。这些概念就像网格的骨架,帮助我们精确地描述和控制布局效果。
- 网格线是整个网格系统的基础。它是网格中那些看不见的分界线,用来划分网格空间。网格线可以是水平的,也可以是垂直的,它们构成了网格的基本框架。
- 网格轨道是相邻两条网格线之间的空间。在水平方向,我们称之为行轨道;在垂直方向,我们称之为列轨道。网格轨道的大小决定了网格项目的尺寸。
- 网格单元是网格中最小的空间单位,由四条网格线围成的矩形区域。虽然我们通常不会直接操作网格单元,但它是理解网格布局的基础。
- 网格区域则是由多个网格单元组成的矩形区域。它可以跨越多行多列,为大型内容提供了展示空间。
<!DOCTYPE html>
<html>
<head>
<style>
.grid-demo {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 80px 80px;
gap: 5px
网格项目的概念也需要我们特别关注。网格容器的直接子元素自动成为网格项目,它们会按照网格规则进行排列。网格项目可以跨越多个网格轨道,也可以重叠放置,为布局设计提供了极大的灵活性。
网格线、轨道、单元和区域这些概念共同构成了网格布局的理论基础。
构建网格框架
网格布局的真正威力在于我们能够精确控制网格轨道的大小和位置。通过精心设计的轨道尺寸,我们可以创建出各种复杂的布局结构。
网格模板属性
在CSS网格布局(Grid)中,grid-template-rows 和 grid-template-columns 这两个属性是用来精确定义网格“轨道”——也就是每一行和每一列的尺寸和数量的核心工具。
grid-template-rows:用于设置每一行的高度。例如:grid-template-rows: 100px 1fr 2fr; 就是先后定义三行,高度分别为100像素、1单位比例、2单位比例。每当你在这个属性中写一个值,就实际创建了一条行轨道和其两端的网格线。
grid-template-columns:用于设置每一列的宽度,比如:grid-template-columns: 200px auto 1fr; 表示三列,宽度分别是200像素、自适应、1比例份额。每指定一个列宽,同样会自动在该列的两侧生成网格线。
实际上,这两个属性不仅决定了网格的分割方式,也决定了网格线(Grid Lines)的位置。每添加一个轨道值(无论是行还是列),CSS都会自动在两侧插入一条网格线。例如,定义三行时,实际上有四条水平方向的网格线。同理,三列就会有四条竖直方向的网格线。
这种设计让你可以非常灵活地定位网格项目的位置——比如让某个元素跨越第1到第3条列线,从而“横跨”两列。合理地规划轨道尺寸和数量,是实现复杂网格布局的基础。
<!DOCTYPE html>
<html>
<head>
<style>
.grid-layout {
display: grid;
grid-template-columns: 200px 1fr 100px;
grid-template-rows: 50px 100px 50px;
gap:
为网格线命名
通常我们在使用 CSS 网格布局时,可以用数字(如 1、2、3)来引用网格线。但实际上,为了让布局更加清晰易懂,CSS 也允许我们为网格线赋予自定义的名字。有了名称,我们可以在放置或跨越网格元素时,直接用有意义的单词而不是数字来描述它们的位置,这让大型布局的维护和阅读都变得更加容易。
具体怎么命名?在设置 grid-template-rows 或 grid-template-columns 时,只要把想给网格线起的名字写在方括号 [] 里,并放在轨道尺寸(如 1fr、200px)前后。例如:
grid-template-columns:
[sidebar-start] 200px [sidebar-end content-start] 1fr [content-end];
这里 [sidebar-start]、[sidebar-end]、[content-start] 和 [content-end] 都是网格线的名字。一个网格轨道的尺寸前后的两个网格线都可以分别命名,甚至可以同时为一条线设置多个名字(用空格分隔)。
每当你写了一个轨道单位(比如 1fr 或 200px),前面和后面都可以加名字——这样你就可以用“header-start”,“main-end”等更直观的方式来定位内容区域,而不必死记第几条网格线是哪一根。这种命名机制大大提升了 CSS 网格在构建复杂页面时的可维护性和可读性。
<!DOCTYPE html>
<html>
<head>
<style>
.named-grid {
display: grid;
grid-template-columns:
[site-start] 200px [content-start] 1fr [content-end] 200px [site-end];
grid-template-rows:
[header-start] 60px [header-end main-start]
在上面的示例中,我们为网格线赋予了富有语义的名字,如site-start、content-start等。这些名字让代码的意图更加清晰,即使在几个月后重新查看代码,我们也能一眼理解布局的结构。
网格线的命名不仅提高了代码的可读性,还为后续的布局调整提供了便利。当我们需要修改布局时,可以直接通过名字引用网格线,而不必记住具体的数字位置。
轨道尺寸
网格轨道(Grid Track)的尺寸控制是 CSS 网格布局中最核心、最关键的部分之一。通过灵活设置轨道尺寸,我们能够精准地塑造页面的结构,既可以实现严密对齐,也能满足响应式布局的需求。轨道尺寸的设定不仅影响每一个网格单元(cell)的大小,还决定了整个网格容器在不同屏幕和内容场景下的表现。
在 CSS Grid 中,我们主要有以下几种方式来定义网格轨道的尺寸,每一种方式适用于不同的应用场景,并各有其技术优缺点:
固定尺寸轨道(Fixed Track Size)
固定尺寸轨道指的是使用明确的长度单位(如像素 px、相对单位 em、rem,或百分比 %)来定义每一行或每一列的大小。这种方式的特点是轨道尺寸始终保持不变,无论容器尺寸、窗口宽度还是内容多少,都不会影响轨道本身的宽度或高度。例如:
grid-template-columns: 200px 300px 200px;
grid-template-rows: 50px 100px;
grid-template-columns: 20% 60% 20%;
这种方法适合于那些对布局有明确严格尺寸要求的场合,常见于导航栏、侧边栏、固定页脚等模块。优点是布局可控性极强,避免超出预期的变形;缺点是弹性和自适应能力有限,可能在不同设备上不如各种相对单位和比例单位灵活。
<!DOCTYPE html>
<html>
<head>
<style>
.fixed-grid {
display: grid;
grid-template-columns: 150px 300px 150px;
grid-template-rows: 80px 120px;
gap: 15px
灵活尺寸轨道
fr(fraction,份额)单位是CSS网格布局(Grid Layout)中特有的长度单位,它用于表示“可用空间”的等分。和像素(px)或百分比(%)不同,fr是动态、弹性的,能够让浏览器根据容器的剩余空间,将空间按比例平均或配比分配给各个轨道(行或列)。
例如,grid-template-columns: 1fr 2fr 1fr; 表示这一行被分成4份,第一列占1份,第二列占2份,第三列再占1份——空间会根据容器的宽度自动分配,从而适应不同屏幕和内容的需要。这种机制极大提升了布局的灵活性和响应性,让复杂的自适应设计变得既专业又易于控制。
简言之,fr单位的作用,就是让网格轨道能够“智能地”瓜分容器剩余的空间,实现先进且通俗易懂的弹性布局效果。
<!DOCTYPE html>
<html>
<head>
<style>
.flexible-grid {
display: grid;
grid-template-columns: 200px 1fr 2fr 200px;
grid-template-rows: 60px 1fr 60px;
在上面的示例中,1fr 2fr意味着中间的可用空间被分成三份,其中第一部分给第一个fr轨道,剩下的两份给第二个fr轨道。这种分数分配方式让布局能够智能地适应不同的屏幕尺寸。
minmax函数
minmax() 函数是 CSS 网格布局中用于设置轨道尺寸的强大工具。它允许开发者为某个网格行或列同时指定最小值和最大值,从而实现“弹性”轨道:当空间不足时,轨道会收缩到最小值,而当空间充裕时可以扩展到最大值。
例如,写成 minmax(150px, 300px),意味着该轨道最窄不会小于 150 像素,最宽不会超过 300 像素。如果将最大值设置为 1fr 这样的比例单位,则轨道会根据剩余空间和布局需求灵活调整,但绝不会小于指定的最小尺寸。
这样设计可以有效防止内容溢出或者缩到难以阅读,打造既美观又实用的响应式布局。简单来说,minmax() 就是精细约束轨道弹性范围,让布局在不同屏幕下都能保持合理形态。
<!DOCTYPE html>
<html>
<head>
<style>
.minmax-grid {
display: grid;
grid-template-columns: minmax(150px, 300px) 1fr minmax(100px, 200px);
grid-template-rows
内容感知尺寸
CSS 网格布局中的尺寸关键字——如 min-content、max-content 和 fit-content()——为我们提供了强大的内容自适应能力。
min-content 表示轨道会收缩到刚好能容纳其内容的不换行最小宽度(或高度);
max-content 则让轨道扩展到可以完全展示内容而不需换行的最大宽度(或高度);
fit-content(<length>) 允许我们设置一个最大宽度的上限:轨道宽度在内容自适应(不小于最小内容宽度,不超过最大内容宽度)和给定上限之间自动调整。
这些关键字让网格轨道可以灵活响应内容长度,大大提升了布局的适应性和可读性——不用再为过长或过短的内容担心溢出或空白问题,非常适合设计复杂、变化多端的页面结构。
<!DOCTYPE html>
<html>
<head>
<style>
.content-aware-grid {
display: grid;
grid-template-columns: max-content 1fr min-content;
grid-template-rows: min-content 1fr;
gap: 20px;
background-color
max-content让轨道宽度正好容纳最宽的内容,min-content则让轨道尽可能窄但仍能容纳内容,而fit-content()则在两者之间提供了一个平衡点。
不同的轨道尺寸策略各有优势:固定尺寸提供精确控制,灵活尺寸适应不同屏幕,内容感知尺寸则让布局更加自然。这些工具的合理组合能够创造出既美观又实用的界面设计。
重复模式
在实际的网页设计中,我们经常需要创建具有重复模式的布局结构。CSS网格提供了强大的重复功能,让我们能够轻松地生成一系列相同或相似的轨道。
repeat()函数
repeat()函数是网格布局中最实用的工具之一,它允许我们用简洁的语法定义多个相同的轨道。
<!DOCTYPE html>
<html>
<head>
<style>
.repeat-grid {
display: grid;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(3, 80px);
gap:
repeat(4, 100px)相当于写出了四个100px轨道。这种简洁的语法不仅减少了代码量,还提高了可维护性。
复杂重复模式
repeat函数的强大之处不仅在于能重复单一的轨道尺寸(比如 repeat(4, 100px) 代表4个100px宽的轨道),更在于它可以重复一组不同的轨道模式。也就是说,repeat(n, a b) 会将a b这一组轨道按照指定次数整体重复,实现“交替混合”的网格分布。例如,grid-template-columns: repeat(3, 150px 1fr) 实际上等价于 150px 1fr 150px 1fr 150px 1fr,创建了三组“150像素+剩余空间”的交替结构。
这种用法让我们能够以极其简洁的语法,快速实现富有规律性、带交错、等距或宽窄错落有致的复杂网格布局,极大提升页面的专业感与结构表达力。
<!DOCTYPE html>
<html>
<head>
<style>
.complex-repeat {
display: grid;
grid-template-columns: repeat(3, 150px 1fr);
grid-template-rows: 60px 1fr 60px;
在这个例子中,repeat(3, 150px 1fr)创建了三组150px 1fr的模式,总共六个列轨道。
自动填充轨道
在实际布局中,我们经常遇到这样的问题:容器宽度是动态变化的,但我们希望每个网格轨道的尺寸固定或最小/最大可控,同时还能让轨道数量自动适应可用空间。这时,CSS Grid 提供的 auto-fill 和 auto-fit 关键字就是专业且高效的解决方案。
auto-fill 和 auto-fit 可以与 repeat() 函数配合使用,根据容器的实际宽度,自动填充或适应尽可能多的轨道(列)。它们允许我们用一行代码动态生成适当数量的列,无需手动指定列数。当你把它们和 minmax() 结合使用时,每个轨道就能在指定的最小和最大宽度之间自适应调整,非常适合响应式页面设计。
通俗地说,auto-fill 就像是“尽量多塞几个格子进去”,而 auto-fit 则会智能压缩空余轨道,使其进一步拉伸填满容器。二者都极大地提升了布局的灵活性和自动化程度,让网格在不同屏幕和窗口尺寸下都能优雅展示。
<!DOCTYPE html>
<html>
<head>
<style>
.auto-fill-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 15px;
background-color
auto-fill会尽可能多地创建轨道,即使有些轨道是空的。而auto-fit则会压缩空的轨道,让有内容的轨道能够扩展占据更多空间。
网格区域
网格区域(Grid Areas)是 CSS 网格布局中最强大与直观的功能之一,也是构建复杂页面布局的“核心利器”。通过灵活划分网格区域,我们能像搭积木一样,将网页结构拆解成若干命名板块,每个板块代表内容的一个语义部分,比如“头部(header)”、“侧边栏(sidebar)”、“主内容(content)”等。
利用网格区域可以彻底摆脱传统布局中繁琐的嵌套结构和样式耦合,使得排版更“语义化”,也便于多人协作开发和后期维护。事实上,大型网站和企业级后台系统的页面框架几乎都大量采用了网格区域技术,实现高效、规范且可扩展的模块化布局。
<!DOCTYPE html>
<html>
<head>
<style>
.area-placement {
display: grid;
grid-template-areas:
"masthead masthead masthead masthead"
"navigation main main sidebar"
"navigation footer footer footer";
grid-template-rows: 80px 1fr 60px;
grid-template-columns
grid-area属性是 CSS Grid 布局中用于元素区域定位的核心工具。它允许我们直接将某个元素分配到在grid-template-areas中预先命名的区域,无需繁琐的行列数值坐标。例如,grid-area: header;会让该元素自动覆盖整个"header"区域,即使这个区域跨多个单元格。
这种区域命名与分配的模式,有助于将HTML结构中的语义分区(如<header>、<nav>、<main>、<footer>等)与CSS布局层完全解耦,使布局和内容分离,不仅代码更易于理解和维护,还能极大提升协作开发的效率与页面结构的可扩展性。
区域命名的自动网格线
在使用 grid-template-areas 定义网格区域时,CSS 会自动为每个区域生成对应的命名网格线。这些“命名网格线”就像给网格的每一个边界贴上了标识,让我们能够像引用变量一样,通过诸如 grid-column: header-start / header-end 这样的语法精准地控制元素的起始和结束位置。这一机制极大提升了布局的语义性和可维护性:只需在模板里命名区域,无需手动编号复杂的行线,布局定位变得既直观又灵活。比如,header 区域会自动产生 header-start 和 header-end 这样的网格线名称,方便我们在后续 CSS 中随时引用,实现高度可读、模块化的页面分区和调整。
<!DOCTYPE html>
<html>
<head>
<style>
.auto-lines {
display: grid;
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
grid-template-rows: 60px 1fr 50px;
grid-template-columns:
每个网格区域都会自动创建-start和-end后缀的网格线名称,这些名称可以直接在其他网格属性中使用。
精确定位
网格布局的一大核心优势,就是能够精确且灵活地控制每一个元素的摆放位置。我们不仅可以让元素“自动”跟随模板分布,还可以通过详细的属性,手动指定单元格的起止点,实现跨行、跨列,甚至覆盖多个区域,打造出高度复杂且专业的页面结构。
网格线定位
所谓“网格线”,就是 CSS Grid 布局中对每条分隔线的标记和编号。通过grid-row-start、grid-row-end、grid-column-start和grid-column-end等属性,我们可以直接引用网格线的编号或自定义名称,精确指定元素的起始和结束位置。这意味着,只需要指定元素的“起止线”,就能决定它的位置和跨越多少格,相较于以往的布局方式,这种方法更直观、更专业,而且极大提升了页面排版的可控性和可读性。
举个例子,如果你希望某个项目横跨网格的第2到第4列,同时跨越第1到第3行,只需这样写:
.item {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
你也可以使用网格线上自定义的名字,从而使大型项目协作和维护更加轻松。
<!DOCTYPE html>
<html>
<head>
<style>
.line-positioning {
display: grid;
grid-template-columns: [start] 100px [col2] 100px [col3] 100px [end];
grid-template-rows: [row1] 80px [row2]
span关键字
在 CSS Grid 布局中,span 关键字是用于简化元素跨越多个网格轨道(列或行)写法的专业工具。通常,如果你想让某个元素横跨若干列或行,可以不用手动写出结束线的具体编号或名称,而是直接通过 span N(N为数字)指定该元素需要跨越的“格数”。
例如:grid-column-end: span 3; 意味着当前元素会从其起始线开始,横向占据 3 个网格宽度,无需关心终止线的实际索引。这种写法既直观又有利于后续调整网格轨道数,极大提升了布局的灵活性和代码可维护性。尤其在响应式或动态网格设计场景下,span 关键字能让布局变得更加“弹性”和高效,降低出错概率,非常适合专业级页面构建。
通俗地说,span 就像告诉网格系统:“帮我自动跨越后面 N 个格子”,不用费心数轨道号,尤其在复杂大网格中优势更加明显。
<!DOCTYPE html>
<html>
<head>
<style>
.span-positioning {
display: grid;
grid-template-columns: repeat(6, 80px);
grid-template-rows: repeat(4, 60px);
gap:
grid-row和grid-column
在 CSS 网格布局中,grid-row 和 grid-column 是分别用来同时指定起始线和结束线的简写属性。
具体来说,grid-row: 起始线 / 结束线; 相当于同时设置了 grid-row-start 和 grid-row-end,而 grid-column: 起始线 / 结束线; 则同时覆盖 grid-column-start 和 grid-column-end。无论是采用数字编号、命名网格线,还是使用 span 跨越多行(列),都可以通过这种方式一行描述,大大降低了出错率。例如:
.item {
grid-row: 1 / span 2; /* 从第1条行线开始,跨2行 */
grid-column: col1 / col3; /* 从col1线到col3线 */
}
<!DOCTYPE html>
<html>
<head>
<style>
.shorthand-positioning {
display: grid;
grid-template-columns: [col1] 120px [col2] 120px [col3] 120px [col4];
grid-template-rows: [row1] 70px [row2] 70px [row3] 70
自动定位与网格流
在 CSS Grid 布局中,如果没有为每个网格项目指定具体的行列起止点(如 grid-row 或 grid-column),这些项目会自动按照“网格流”(grid flow)规则依次安放。这个“自动分配”的过程由 grid-auto-flow 属性专业掌控。
grid-auto-flow 属性决定了网格容器如何自动填充未明确定位的子元素,其常用取值有 row(默认,沿着行优先填充)、column(沿着列优先填充),以及 dense(密集打包,尽量利用每一个空隙)。你可以通过调整 grid-auto-flow,精细控制布局时未被手动指定位置的元素究竟是优先横向还是纵向排列,以及是否允许元素“回补”空白区。
<!DOCTYPE html>
<html>
<head>
<style>
.auto-flow-row {
display: grid;
grid-auto-flow: row;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(2, 60
网格元素放置技术为我们提供了精确控制布局的强大工具。从简单的网格线引用到复杂的跨越定位,每种方法都有其适用的场景。合理组合这些技术,能够创造出既灵活又精确的布局效果。
智能布局
CSS 网格布局不仅可以通过grid-template-rows和grid-template-columns等属性明确声明网格的行和列(这部分被称为“显式网格”),还具备灵活管理未预定义范围之外内容的能力——这便是“隐式网格”的概念。
在专业开发场景中,我们经常遇到元素数量超出原本声明网格的情况。此时,CSS Grid 会自动为这些“溢出”的项目动态生成额外的行或列轨道,用于容纳它们,这就是隐式网格轨道(implicit grid tracks)。
简单来说:只要有内容“放不下”,CSS 网格就会自动扩容补位,无需手动写新轨道。这种智能补全机制,极大提升了页面的弹性和容错能力,非常适合内容异步加载、响应式布局或动态模块场景。
- 显式网格:通过
grid-template-rows 和 grid-template-columns 指定的轨道范围内的网格。
- 隐式网格:当元素数超出显式网格最大行列时,CSS Grid 会根据
grid-auto-rows 和 grid-auto-columns 的定义补充新轨道(不设置则用自动高度/宽度)。
例如我们声明了3行3列,但有个项目被强制放在第4列或第4行,Grid 会自动补出第4列/行,并用相关自动轨道尺寸属性控制。
<!DOCTYPE html>
<html>
<head>
<style>
.implicit-grid {
display: grid;
grid-template-rows: 60px 60px;
grid-template-columns: 100px 100px 100px;
grid-auto-rows: 50px
grid-auto-rows和grid-auto-columns属性控制隐式创建的轨道尺寸,为超出显式网格的内容提供一致的布局环境。
子网格
在复杂页面布局中,**子网格(subgrid)**是 CSS Grid 提供的专业级工具。它允许嵌套的网格(内部grid容器)直接“继承”父级的网格轨道定义(行和列的起止线),从而让多层嵌套的内容严格对齐。
通俗来说,如果外部已经用网格分好了“列宽”或“行高”,子网格就不必重复再定义一次,而是复用父网格的分割方式——这样无论嵌套多深,都能保证每一层内容边界精准一致,视觉效果整齐,维护起来也非常高效。对于响应式设计和组件化开发,这种继承特性尤为重要,可以最大限度减少重复代码和调整成本。
要启用子网格,只需在子 grid 容器上设置 grid-template-columns: subgrid; 或 grid-template-rows: subgrid;。
专业表达:
grid-template-columns: subgrid; 让子网格的列轨道完全跟随父级,无需再单独声明列宽。
grid-template-rows: subgrid; 则让行轨道继承父网格设定。
<!DOCTYPE html>
<html>
<head>
<style>
.parent-grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 80px 1fr 60px;
gap:
完美对齐
跟弹性盒子一样,网格布局为开发者提供了一整套强大且细致的对齐机制,不仅能让每个元素在单元格中“精确落位”,还支持整个网格的整体对齐。这使得复杂排版与视觉平衡变得简单而高效。
CSS 网格的对齐分为“单元格内”和“网格整体”两个层面:
-
单元格内对齐
justify-self:控制单元格内元素在水平方向(主轴,沿着行)上的对齐方式。可选值有 start(靠左)、end(靠右)、center(居中)、stretch(默认,占满)。
align-self:控制单元格内元素在垂直方向(交叉轴,沿着列)上的对齐。可选值同上,比如 start 表示单元格顶部,end 为底部等。
- 这两个属性主要用于单独、精细地定位每一个网格子元素。
-
网格整体对齐
justify-items:设置所有网格子元素的水平方向对齐(相当于为每个子项批量指定 justify-self)。
align-items:设置所有网格子元素的垂直方向对齐(类似为每个子项批量指定 align-self)。
- 方便又专业,让整个模块一键切换布局风格。
有了这些属性,无论是让单个区块精确摆放,还是统一全局的视觉风格,都能实现“所见即所得”的精确对齐效果。
<!DOCTYPE html>
<html>
<head>
<style>
.alignment-grid {
display: grid;
grid-template-columns: 150px 150px 150px;
grid-template-rows: 100px 100px;
gap: 10px
小结
CSS 网格布局是前端开发中极为强大且灵活的布局工具。通过理解其基本原理以及灵活运用各类属性,我们能够设计出既美观又实用的界面。
在实际应用中,应坚持让内容驱动结构、渐进增强、语义化命名以及模块化设计,将复杂布局拆解为易于管理的区域,同时注意避免过度嵌套、合理利用隐式网格,并关注移动端的性能表现,以实现高效和适应性强的布局方案。
实战练习
练习一:网格容器创建
请问以下哪个CSS属性可以将一个元素转换为网格容器?
- .
display: flex
- .
display: grid
- .
display: block
- .
display: table
答案:B. display: grid
display: grid 是创建网格容器的正确方法。当我们为一个元素设置 display: grid 时,该元素就成为了网格容器,其直接子元素会自动成为网格项目。
练习二:理解网格术语
网格轨道是相邻两条网格线之间的空间。在水平方向的网格轨道我们称为什么?
- A. 列轨道
- B. 行轨道
- C. 网格单元
- D. 网格区域
答案:B. 行轨道
在水平方向的网格轨道称为行轨道(row track),在垂直方向的网格轨道称为列轨道(column track)。
练习三:fr单位的使用
在CSS网格布局中,grid-template-columns: 1fr 2fr 1fr; 这行代码表示什么?
- A. 三列等宽
- B. 第一列和第二列等宽,第三列是它们的两倍
- C. 三列按1:2:1的比例分配剩余空间
- D. 第一列和第三列等宽,第二列是它们的两倍
答案:C. 三列按1:2:1的比例分配剩余空间
fr(fraction)单位表示可用空间的比例分配。1fr 2fr 1fr 意味着将可用空间分成4份(1+2+1),第一列占1份,第二列占2份,第三列占1份,因此第二列的宽度是第一列和第三列的两倍。
练习四:repeat函数
以下哪个选项等价于 grid-template-columns: 100px 100px 100px 100px;?
- A.
grid-template-columns: repeat(3, 100px);
- B.
grid-template-columns: repeat(4, 100px);
- C.
grid-template-columns: repeat(100px, 4);
- D.
grid-template-columns: repeat(4, 1fr);
答案:B. grid-template-columns: repeat(4, 100px);
repeat() 函数的语法是 repeat(次数, 尺寸)。要创建4个100px宽的列,应该写成 repeat(4, 100px)。
练习五:minmax函数
minmax(150px, 300px) 表示什么?
- A. 轨道宽度固定为150px
- B. 轨道宽度固定为300px
- C. 轨道宽度在150px到300px之间,根据可用空间调整
- D. 轨道宽度最小150px,最大可以是任意值
答案:C. 轨道宽度在150px到300px之间,根据可用空间调整
minmax(最小值, 最大值) 函数创建一个弹性轨道,其宽度(或高度)不会小于最小值,也不会大于最大值。在这个例子中,轨道宽度会在150px和300px之间根据可用空间自动调整。
练习六:网格区域命名
在使用 grid-template-areas 定义网格区域时,如果我们定义了名为 header 的区域,CSS会自动生成哪些网格线名称?
- A.
header 和 header-line
- B.
header-start 和 header-end
- C.
header-top 和 header-bottom
- D. 不会自动生成,需要手动命名
答案:B. header-start 和 header-end
当我们在 grid-template-areas 中定义一个区域(如 header)时,CSS会自动为该区域生成对应的网格线名称:header-start 和 header-end。这些名称可以在 grid-column 或 grid-row 等属性中使用。
练习七:span关键字
如果一个网格项目设置了 grid-column-end: span 3;,这意味着什么?
- A. 该元素从第3列开始
- B. 该元素横跨3个网格列
- C. 该元素在第3列结束
- D. 该元素占据3行的高度
答案:B. 该元素横跨3个网格列
span 关键字用于指定元素跨越的轨道数量。grid-column-end: span 3; 表示该元素会从其起始列线开始,横向跨越3个网格列。
练习八:grid-row和grid-column简写
grid-row: 1 / span 2; 等价于以下哪组代码?
- A.
grid-row-start: 1; grid-row-end: 2;
- B.
grid-row-start: 1; grid-row-end: span 2;
- C.
grid-row-start: span 2; grid-row-end: 1;
- D.
grid-row-start: 2; grid-row-end: span 1;
答案:B. grid-row-start: 1; grid-row-end: span 2;
grid-row: 1 / span 2; 是 grid-row-start 和 grid-row-end 的简写形式。它表示从第1条行线开始,跨越2行,等价于 grid-row-start: 1; grid-row-end: span 2;。
练习九:隐式网格
当我们声明了一个3行3列的显式网格,但有一个元素被放置在第4行,CSS网格会如何处理?
- A. 报错,元素无法放置
- B. 自动创建第4行(隐式网格轨道)
- C. 将元素放置在最后一行
- D. 忽略该元素
答案:B. 自动创建第4行(隐式网格轨道)
CSS网格会自动为超出显式网格范围的元素创建隐式网格轨道。如果元素被放置在第4行,而只定义了3行,网格会自动创建第4行来容纳该元素。隐式轨道的尺寸由 grid-auto-rows 或 grid-auto-columns 属性控制。
练习十:对齐属性
如果我们想让网格容器中的所有子元素都在各自的单元格中水平居中,应该使用哪个属性?
- A.
justify-items: center;
- B.
align-items: center;
- C.
justify-self: center;
- D.
place-items: center;
答案:A. justify-items: center;
justify-items 属性用于设置所有网格子元素在水平方向(沿着行)的对齐方式。justify-items: center; 会让所有子元素在各自的单元格中水平居中。align-items 控制垂直方向的对齐,justify-self 只作用于单个元素,place-items 是 align-items 和 justify-items 的简写。
练习十一:auto-fill和auto-fit的区别
repeat(auto-fill, minmax(150px, 1fr)) 和 repeat(auto-fit, minmax(150px, 1fr)) 的主要区别是什么?
- A. 没有区别,两者完全相同
- B.
auto-fill 会创建尽可能多的轨道,即使有些是空的;auto-fit 会压缩空轨道,让有内容的轨道扩展
- C.
auto-fit 会创建尽可能多的轨道,auto-fill 会压缩空轨道
- D. 两者都只能用于行轨道
答案:B. auto-fill 会创建尽可能多的轨道,即使有些是空的;auto-fit 会压缩空轨道,让有内容的轨道扩展
auto-fill 和 auto-fit 都能根据容器宽度自动创建轨道。关键区别在于:auto-fill 会尽可能多地创建轨道(根据 minmax 的最小值计算),即使有些轨道是空的也会保留;而 auto-fit 会压缩空的轨道,让有内容的轨道扩展以填充可用空间。
练习十二:网格线命名
以下代码中,[sidebar-start] 和 [content-start] 之间有几个轨道?
grid-template-columns: [sidebar-start] 200px [sidebar-end content-start] 1fr [content-end];
答案:B. 1个
在网格线命名中,[sidebar-end content-start] 表示同一条网格线有两个名称。因此,[sidebar-start] 和 [content-start] 之间只有1个轨道,即宽度为200px的侧边栏轨道。网格线的命名允许一条线拥有多个名称,这在复杂布局中非常有用。
:
#4CAF50
;
color: white;
padding: 20px;
text-align: center;
}
</style>
</head>
<body>
<div class="grid-container">
<div class="grid-item">项目1</div>
<div class="grid-item">项目2</div>
<div class="grid-item">项目3</div>
</div>
</body>
</html>
;
background-color: #ddd;
padding: 10px;
}
.grid-item {
background-color: #2196F3;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
</style>
</head>
<body>
<div class="grid-demo">
<div class="grid-item">网格线划分空间</div>
<div class="grid-item">轨道决定尺寸</div>
<div class="grid-item">单元是最小单位</div>
<div class="grid-item">区域可以跨越多个</div>
<div class="grid-item">网格线</div>
<div class="grid-item">轨道</div>
</div>
</body>
</html>
10
px
;
background-color: #f5f5f5;
padding: 20px;
}
.grid-item {
background-color: #FF6B6B;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="grid-layout">
<div class="grid-item">标题区域</div>
<div class="grid-item">导航栏</div>
<div class="grid-item">侧边栏</div>
<div class="grid-item">主内容</div>
<div class="grid-item">页脚</div>
</div>
</body>
</html>
1
fr
[main-end footer-start]
40
px
[footer-end];
gap: 15px;
background-color: #e8f4f8;
padding: 20px;
min-height: 300px;
}
.header {
grid-column: site-start / site-end;
grid-row: header-start / header-end;
background-color: #2E86AB;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.sidebar {
grid-column: site-start / content-start;
grid-row: main-start / main-end;
background-color: #A23B72;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.content {
grid-column: content-start / content-end;
grid-row: main-start / main-end;
background-color: #F18F01;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.footer {
grid-column: site-start / site-end;
grid-row: footer-start / footer-end;
background-color: #C73E1D;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="named-grid">
<div class="header">网站标题</div>
<div class="sidebar">侧边导航</div>
<div class="content">主要内容</div>
<div class="footer">网站页脚</div>
</div>
</body>
</html>
;
background-color: #f8f9fa;
padding: 20px;
}
.grid-item {
background-color: #6c757d;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
border-radius: 6px;
}
.wide-content {
background-color: #28a745;
}
</style>
</head>
<body>
<div class="fixed-grid">
<div class="grid-item">侧边栏</div>
<div class="grid-item wide-content">主要内容区域</div>
<div class="grid-item">工具栏</div>
<div class="grid-item">导航</div>
<div class="grid-item">信息面板</div>
<div class="grid-item">设置</div>
</div>
</body>
</html>
gap: 20px;
background-color: #e9ecef;
padding: 20px;
min-height: 300px;
}
.grid-item {
background-color: #495057;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
border-radius: 6px;
}
.header { background-color: #007bff; }
.sidebar { background-color: #6f42c1; }
.content { background-color: #28a745; }
.aside { background-color: #fd7e14; }
.footer { background-color: #dc3545; }
</style>
</head>
<body>
<div class="flexible-grid">
<div class="grid-item header">网站标题</div>
<div class="grid-item header">用户菜单</div>
<div class="grid-item header">搜索框</div>
<div class="grid-item header">快捷链接</div>
<div class="grid-item sidebar">导航菜单</div>
<div class="grid-item content">主要文章内容</div>
<div class="grid-item aside">相关推荐</div>
<div class="grid-item sidebar">广告位</div>
<div class="grid-item footer">版权信息</div>
<div class="grid-item footer">友情链接</div>
<div class="grid-item footer">联系方式</div>
<div class="grid-item footer">站点地图</div>
</div>
</body>
</html>
:
minmax
(
50
px
,
100
px
)
1
fr
minmax
(
40
px
,
80
px
);
gap: 15px;
background-color: #f8f9fa;
padding: 20px;
min-height: 300px;
}
.grid-item {
background-color: #17a2b8;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
padding: 10px;
}
</style>
</head>
<body>
<div class="minmax-grid">
<div class="grid-item">标题栏<br>高度自适应</div>
<div class="grid-item">搜索区域<br>灵活扩展</div>
<div class="grid-item">用户头像</div>
<div class="grid-item">侧边导航<br>固定宽度范围</div>
<div class="grid-item">主要内容<br>占据剩余空间</div>
<div class="grid-item">右侧工具栏<br>宽度可变</div>
<div class="grid-item">页脚链接</div>
<div class="grid-item">版权声明</div>
<div class="grid-item">社交媒体</div>
</div>
</body>
</html>
:
#e9ecef
;
padding: 20px;
min-height: 300px;
}
.grid-item {
background-color: #6f42c1;
color: white;
padding: 15px;
border-radius: 6px;
font-size: 14px;
}
.title {
background-color: #e83e8c;
font-weight: bold;
}
.content {
background-color: #20c997;
}
</style>
</head>
<body>
<div class="content-aware-grid">
<div class="grid-item title">页面标题很长很长</div>
<div class="grid-item content">主要内容区域会自动填充剩余空间</div>
<div class="grid-item">短文本</div>
<div class="grid-item content">侧边栏内容<br>根据内容调整宽度</div>
<div class="grid-item content">文章主体<br>灵活占据空间<br>可以包含多行内容</div>
<div class="grid-item">操作按钮</div>
</div>
</body>
</html>
10
px
;
background-color: #f8f9fa;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
.special {
background-color: #28a745;
grid-column: span 2;
}
</style>
</head>
<body>
<div class="repeat-grid">
<div class="grid-item">项目1</div>
<div class="grid-item">项目2</div>
<div class="grid-item special">跨两列的项目</div>
<div class="grid-item">项目4</div>
<div class="grid-item">项目5</div>
<div class="grid-item">项目6</div>
<div class="grid-item">项目7</div>
<div class="grid-item">项目8</div>
<div class="grid-item">项目9</div>
<div class="grid-item">项目10</div>
</div>
</body>
</html>
gap: 15px;
background-color: #e9ecef;
padding: 20px;
min-height: 300px;
}
.grid-item {
background-color: #6f42c1;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
.header { background-color: #007bff; }
.content { background-color: #28a745; }
.sidebar { background-color: #fd7e14; }
.footer { background-color: #dc3545; }
</style>
</head>
<body>
<div class="complex-repeat">
<div class="grid-item header">Logo</div>
<div class="grid-item header">导航菜单</div>
<div class="grid-item header">搜索框</div>
<div class="grid-item header">用户中心</div>
<div class="grid-item header">设置</div>
<div class="grid-item header">帮助</div>
<div class="grid-item sidebar">侧边栏</div>
<div class="grid-item content">主要内容</div>
<div class="grid-item sidebar">工具面板</div>
<div class="grid-item content">文章列表</div>
<div class="grid-item sidebar">快捷操作</div>
<div class="grid-item content">推荐内容</div>
<div class="grid-item footer">版权信息</div>
<div class="grid-item footer">联系方式</div>
<div class="grid-item footer">隐私政策</div>
<div class="grid-item footer">使用条款</div>
<div class="grid-item footer">站点地图</div>
<div class="grid-item footer">反馈建议</div>
</div>
</body>
</html>
:
#f8f9fa
;
padding: 20px;
}
.auto-fit-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
background-color: #e9ecef;
padding: 20px;
margin-top: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
padding: 20px;
min-height: 80px;
}
.section-title {
background-color: #6c757d;
grid-column: 1 / -1;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="auto-fill-grid">
<div class="grid-item section-title">auto-fill 示例</div>
<div class="grid-item">项目1</div>
<div class="grid-item">项目2</div>
<div class="grid-item">项目3</div>
<div class="grid-item">项目4</div>
<div class="grid-item">项目5</div>
</div>
<div class="auto-fit-grid">
<div class="grid-item section-title">auto-fit 示例</div>
<div class="grid-item">项目A</div>
<div class="grid-item">项目B</div>
<div class="grid-item">项目C</div>
<div class="grid-item">项目D</div>
</div>
</body>
</html>
:
200
px
1
fr
1
fr
180
px
;
gap: 15px;
background-color: #f8f9fa;
padding: 20px;
min-height: 350px;
}
.masthead {
grid-area: masthead;
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
border-radius: 6px;
}
.navigation {
grid-area: navigation;
background-color: #28a745;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
.main {
grid-area: main;
background-color: #fd7e14;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
border-radius: 6px;
}
.sidebar {
grid-area: sidebar;
background-color: #6f42c1;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
.footer {
grid-area: footer;
background-color: #dc3545;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
</style>
</head>
<body>
<div class="area-placement">
<header class="masthead">网站标题和Logo</header>
<nav class="navigation">导航菜单</nav>
<main class="main">主要内容区域</main>
<aside class="sidebar">侧边栏内容</aside>
<footer class="footer">网站页脚</footer>
</div>
</body>
</html>
180
px
1
fr
1
fr
;
gap: 15px;
background-color: #e9ecef;
padding: 20px;
min-height: 300px;
}
.grid-item {
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
padding: 8px;
}
.header {
grid-area: header;
background-color: #007bff;
}
.sidebar {
grid-area: sidebar;
background-color: #28a745;
}
.content {
grid-area: content;
background-color: #fd7e14;
}
.footer {
grid-area: footer;
background-color: #dc3545;
}
/* 使用自动生成的网格线名称 */
.special-item {
background-color: #6f42c1;
grid-row: header-start / footer-end;
grid-column: sidebar-start / content-end;
position: relative;
z-index: 10;
opacity: 0.8;
}
</style>
</head>
<body>
<div class="auto-lines">
<div class="grid-item header">页面头部</div>
<div class="grid-item sidebar">侧边栏</div>
<div class="grid-item content">主要内容</div>
<div class="grid-item footer">页脚区域</div>
<div class="grid-item special-item">跨区域元素</div>
</div>
</body>
</html>
80
px
[row3]
80
px
[row4];
gap: 10px;
background-color: #f8f9fa;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 6px;
}
.item1 {
grid-column-start: start;
grid-column-end: col2;
grid-row-start: row1;
grid-row-end: row2;
background-color: #28a745;
}
.item2 {
grid-column-start: col3;
grid-column-end: end;
grid-row-start: row1;
grid-row-end: row3;
background-color: #fd7e14;
}
.item3 {
grid-column-start: start;
grid-column-end: col3;
grid-row-start: row2;
grid-row-end: row4;
background-color: #6f42c1;
}
</style>
</head>
<body>
<div class="line-positioning">
<div class="grid-item item1">跨越1-2列,1-2行</div>
<div class="grid-item item2">跨越3-4列,1-3行</div>
<div class="grid-item item3">跨越1-3列,2-4行</div>
</div>
</body>
</html>
8
px
;
background-color: #e9ecef;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
}
.wide-item {
grid-column-start: 1;
grid-column-end: span 3;
grid-row-start: 1;
grid-row-end: span 2;
background-color: #28a745;
}
.tall-item {
grid-column-start: 4;
grid-column-end: span 2;
grid-row-start: 1;
grid-row-end: span 4;
background-color: #fd7e14;
}
.small-item {
grid-column-start: 1;
grid-column-end: span 2;
grid-row-start: 3;
grid-row-end: span 2;
background-color: #6f42c1;
}
</style>
</head>
<body>
<div class="span-positioning">
<div class="grid-item wide-item">宽元素<br>3列×2行</div>
<div class="grid-item tall-item">高元素<br>2列×4行</div>
<div class="grid-item small-item">小元素<br>2列×2行</div>
</div>
</body>
</html>
px
[row4];
gap: 10px;
background-color: #f8f9fa;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
}
.item1 {
grid-row: row1 / span 2;
grid-column: col1 / span 2;
background-color: #28a745;
}
.item2 {
grid-row: row1 / row3;
grid-column: col3 / col4;
background-color: #fd7e14;
}
.item3 {
grid-row: row3 / row4;
grid-column: col1 / span 3;
background-color: #6f42c1;
}
</style>
</head>
<body>
<div class="shorthand-positioning">
<div class="grid-item item1">使用简写<br>row1/span2<br>col1/span2</div>
<div class="grid-item item2">混合定位<br>row1/row3<br>col3/col4</div>
<div class="grid-item item3">跨列布局<br>row3/row4<br>col1/span3</div>
</div>
</body>
</html>
px
);
gap: 10px;
background-color: #f8f9fa;
padding: 20px;
margin-bottom: 20px;
}
.auto-flow-column {
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(2, 60px);
gap: 10px;
background-color: #e9ecef;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
border-radius: 4px;
}
.special {
background-color: #28a745;
grid-column: span 2;
}
</style>
</head>
<body>
<div class="auto-flow-row">
<div class="grid-item">项目1</div>
<div class="grid-item">项目2</div>
<div class="grid-item special">跨列项目</div>
<div class="grid-item">项目4</div>
<div class="grid-item">项目5</div>
</div>
<div class="auto-flow-column">
<div class="grid-item">A</div>
<div class="grid-item">B</div>
<div class="grid-item special">跨行项目</div>
<div class="grid-item">D</div>
<div class="grid-item">E</div>
</div>
</body>
</html>
;
grid-auto-columns: 80px;
gap: 8px;
background-color: #f8f9fa;
padding: 20px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
}
.overflow-item {
background-color: #28a745;
grid-row: 3;
grid-column: 4;
}
</style>
</head>
<body>
<div class="implicit-grid">
<div class="grid-item">显式网格</div>
<div class="grid-item">区域内</div>
<div class="grid-item">的内容</div>
<div class="grid-item">项目</div>
<div class="grid-item">自动</div>
<div class="grid-item">扩展</div>
<div class="grid-item overflow-item">超出边界</div>
</div>
</body>
</html>
15
px
;
background-color: #f8f9fa;
padding: 20px;
min-height: 300px;
}
.subgrid {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
grid-column: 1 / -1;
grid-row: 2;
gap: 8px;
background-color: #e9ecef;
padding: 10px;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
}
.sub-item {
background-color: #28a745;
}
</style>
</head>
<body>
<div class="parent-grid">
<div class="grid-item">父级网格头部</div>
<div class="grid-item subgrid">
<div class="grid-item sub-item">子网格项目1</div>
<div class="grid-item sub-item">子网格项目2</div>
<div class="grid-item sub-item">子网格项目3</div>
</div>
<div class="grid-item">父级网格侧边</div>
<div class="grid-item">父级网格页脚</div>
</div>
</body>
</html>
;
background-color: #f8f9fa;
padding: 20px;
place-items: center;
}
.grid-item {
background-color: #007bff;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border-radius: 4px;
width: 80px;
height: 60px;
}
.start-align {
justify-self: start;
align-self: start;
background-color: #28a745;
}
.center-align {
justify-self: center;
align-self: center;
background-color: #fd7e14;
}
.end-align {
justify-self: end;
align-self: end;
background-color: #6f42c1;
}
.stretch-align {
justify-self: stretch;
align-self: stretch;
background-color: #dc3545;
width: auto;
height: auto;
}
</style>
</head>
<body>
<div class="alignment-grid">
<div class="grid-item start-align">起始对齐</div>
<div class="grid-item center-align">居中对齐</div>
<div class="grid-item end-align">结束对齐</div>
<div class="grid-item stretch-align">拉伸填充</div>
<div class="grid-item">默认居中</div>
<div class="grid-item">网格项目</div>
</div>
</body>
</html>