一文搞定CSS Grid布局

CSS Grid Layout(网格布局)是一个强大的二维布局系统,可以让你轻松地创建复杂的网页布局。

下面内容分为两个主要部分:

  1. 网格容器 (Grid Container) 的属性:应用在父元素上的属性,用于定义网格结构和整体对齐方式。
  2. 网格项目 (Grid Item) 的属性:应用在子元素上的属性,用于定义单个项目在网格中的位置和对齐方式。

准备工作:HTML 结构

我们先定义一个基本的 HTML 结构,用于后续所有的 CSS 示例。

xml 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Grid 布局详解</title>
    <style>
        /* 通用样式,方便观察 */
        .grid-container {
            border: 2px solid black;
            padding: 10px;
            margin-bottom: 20px; /* 分隔不同示例 */
            background-color: lightgrey;
        }
        .grid-item {
            border: 1px solid firebrick;
            background-color: lightcoral;
            padding: 20px;
            text-align: center;
            font-size: 1.2em;
            color: white;
        }

        /* 为不同的项目添加一点区分 */
        .item-1 { background-color: #e67e22; }
        .item-2 { background-color: #2ecc71; }
        .item-3 { background-color: #3498db; }
        .item-4 { background-color: #9b59b6; }
        .item-5 { background-color: #f1c40f; }
        .item-6 { background-color: #1abc9c; }
        .item-7 { background-color: #e74c3c; }
        .item-8 { background-color: #34495e; }
        .item-9 { background-color: #7f8c8d; }
        .item-10 { background-color: #d35400; }
        .item-11 { background-color: #27ae60; }
        .item-12 { background-color: #2980b9; }

    </style>
</head>
<body>

    <h1>CSS Grid 布局详解</h1>

    <!-- 后续的示例将使用类似下面的结构 -->
    <!--
    <div class="grid-container [specific-class-for-example]">
        <div class="grid-item item-1">项目 1</div>
        <div class="grid-item item-2">项目 2</div>
        <div class="grid-item item-3">项目 3</div>
        ...
    </div>
    -->

</body>
</html>

第一部分:网格容器 (Grid Container) 属性

这些属性应用在设置了 display: griddisplay: inline-grid 的元素上。

1. display

  • display: grid; : 将元素定义为块级网格容器。
  • display: inline-grid; : 将元素定义为内联级网格容器。
xml 复制代码
<!-- display: grid 示例 -->
<h2>1. display: grid</h2>
<div class="grid-container display-grid-example">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
</div>
<style>
.display-grid-example {
    display: grid;
    /* 为了看到效果,我们先简单定义列和行 */
    grid-template-columns: 100px 100px;
    grid-template-rows: 50px 50px;
}
</style>

<!-- display: inline-grid 示例 -->
<h2>1. display: inline-grid</h2>
<p>
    这是一个内联网格容器:
    <span class="grid-container display-inline-grid-example">
        <span class="grid-item item-1">1</span>
        <span class="grid-item item-2">2</span>
        <span class="grid-item item-3">3</span>
        <span class="grid-item item-4">4</span>
    </span>
    它会和旁边的文字排在一起。
</p>
<style>
.display-inline-grid-example {
    display: inline-grid; /* 注意这里是 inline-grid */
    grid-template-columns: 60px 60px;
    grid-template-rows: 40px 40px;
    vertical-align: middle; /* 方便观察内联效果 */
}
.display-inline-grid-example .grid-item {
    padding: 5px; /* 调整内联网格项的内边距 */
    font-size: 1em;
}
</style>

2. grid-template-columnsgrid-template-rows

定义网格的列和行的大小和数量。

  • 固定单位 : px, em, rem 等。
  • 百分比 : % 相对于容器尺寸。
  • fr 单位: (fractional unit) 代表网格容器中可用空间的一等份。
  • auto : 由内容或 grid-auto-* 属性决定大小。
  • minmax(min, max) : 定义一个长度范围,表示列/行宽(高)不能小于 min,不能大于 max。
  • repeat(count, sizes) : 重复定义列或行。count 可以是数字,也可以是 auto-fillauto-fit
  • fit-content(limit) : 将轨道大小限制在 limitauto(基于内容)之间。
xml 复制代码
<!-- grid-template-columns / grid-template-rows 示例 -->
<h2>2. grid-template-columns / grid-template-rows</h2>

<h3>2.1 固定单位 (px) 和 百分比 (%)</h3>
<div class="grid-container template-px-percent">
    <div class="grid-item item-1">1 (100px)</div>
    <div class="grid-item item-2">2 (50%)</div>
    <div class="grid-item item-3">3 (150px)</div>
    <div class="grid-item item-4">4 (Row 1: 80px)</div>
    <div class="grid-item item-5">5</div>
    <div class="grid-item item-6">6 (Row 2: 120px)</div>
</div>
<style>
.template-px-percent {
    display: grid;
    grid-template-columns: 100px 50% 150px; /* 第1列100px, 第2列占容器宽度50%, 第3列150px */
    grid-template-rows: 80px 120px;       /* 第1行高80px, 第2行高120px */
}
</style>

<h3>2.2 fr 单位</h3>
<div class="grid-container template-fr">
    <div class="grid-item item-1">1 (1fr)</div>
    <div class="grid-item item-2">2 (2fr)</div>
    <div class="grid-item item-3">3 (1fr)</div>
    <div class="grid-item item-4">4 (Row 1: auto)</div>
    <div class="grid-item item-5">5</div>
    <div class="grid-item item-6">6 (Row 2: 100px)</div>
</div>
<style>
.template-fr {
    display: grid;
    /* 总可用宽度分为 1fr + 2fr + 1fr = 4份 */
    /* 第1列占1/4, 第2列占2/4, 第3列占1/4 */
    grid-template-columns: 1fr 2fr 1fr;
    grid-template-rows: auto 100px; /* 第1行高度由内容决定, 第2行100px */
}
</style>

<h3>2.3 minmax() 函数</h3>
<div class="grid-container template-minmax">
    <div class="grid-item item-1">1 (minmax(100px, 1fr))</div>
    <div class="grid-item item-2">2 (200px)</div>
    <div class="grid-item item-3">3 (minmax(150px, 300px))</div>
</div>
<style>
.template-minmax {
    display: grid;
    /* 第1列:最小100px,最大1fr (占用剩余空间) */
    /* 第2列:固定200px */
    /* 第3列:最小150px,最大300px */
    grid-template-columns: minmax(100px, 1fr) 200px minmax(150px, 300px);
    grid-template-rows: 100px;
}
</style>

<h3>2.4 repeat() 函数</h3>
<div class="grid-container template-repeat">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
    <div class="grid-item item-5">5</div>
    <div class="grid-item item-6">6</div>
</div>
<style>
.template-repeat {
    display: grid;
    /* 定义3列,每列都是 1fr */
    grid-template-columns: repeat(3, 1fr);
    /* 定义2行,模式为:50px, 100px, 50px, 100px... */
    grid-template-rows: repeat(2, 50px 100px); /* 这里会创建4行 */
}
</style>

<h3>2.5 repeat() 与 auto-fill / auto-fit</h3>
<p>尝试改变浏览器窗口大小查看效果。</p>
<h4>auto-fill: 尽可能多地填充列,即使是空的</h4>
<div class="grid-container template-autofill">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
</div>
<style>
.template-autofill {
    display: grid;
    /* 自动填充列,每列最小120px,最大1fr */
    /* auto-fill 会创建尽可能多的轨道,即使没有项目填充它们 */
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    grid-template-rows: 80px;
}
</style>

<h4>auto-fit: 尽可能多地填充列,但会折叠空列</h4>
<div class="grid-container template-autofit">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
</div>
<style>
.template-autofit {
    display: grid;
    /* 自动适应列,每列最小120px,最大1fr */
    /* auto-fit 会将空的轨道折叠为0,让有内容的轨道占据更多空间 */
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    grid-template-rows: 80px;
}
</style>

<h3>2.6 命名网格线 (Named Grid Lines)</h3>
<div class="grid-container template-named-lines">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
</div>
<style>
.template-named-lines {
    display: grid;
    /* 在定义轨道尺寸的同时,用 [] 定义线的名字 */
    grid-template-columns: [col-start] 1fr [col-mid] 1fr [col-end];
    grid-template-rows: [row-start] 100px [row-mid] auto [row-end];
    /* 多个名字用空格隔开: [line-name-1 line-name-2] */
    /* grid-template-columns: [start main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end end]; */
}
/* 如何使用命名线将在 grid-column/grid-row 中演示 */
</style>

3. grid-template-areas

允许你通过引用预定义的网格区域名称来放置网格项目。

  • 用字符串定义每一行。
  • 字符串中的每个单词代表一个单元格,并对应一个区域名称。
  • 使用 . 表示一个空单元格。
  • 相同名称的区域必须形成一个矩形。
xml 复制代码
<!-- grid-template-areas 示例 -->
<h2>3. grid-template-areas</h2>
<div class="grid-container template-areas-example">
    <header class="grid-item item-1 area-header">Header</header>
    <nav class="grid-item item-2 area-nav">Nav</nav>
    <main class="grid-item item-3 area-main">Main Content</main>
    <aside class="grid-item item-4 area-sidebar">Sidebar</aside>
    <footer class="grid-item item-5 area-footer">Footer</footer>
    <!-- 注意:HTML结构中的顺序不重要,CSS中的 grid-area 属性才决定位置 -->
</div>
<style>
.template-areas-example {
    display: grid;
    height: 400px; /* 给容器一个高度以便观察 */
    /* 定义列宽和行高 */
    grid-template-columns: 150px 1fr 150px; /* 左侧导航窄,中间内容宽,右侧边栏窄 */
    grid-template-rows: auto 1fr auto; /* 头部自适应,中间占满剩余,底部自适应 */
    /* 定义网格区域布局 */
    grid-template-areas:
        "header header header"   /* 第1行:header 区域横跨3列 */
        "nav    main   sidebar"  /* 第2行:nav, main, sidebar 各占1列 */
        "footer footer footer";  /* 第3行:footer 区域横跨3列 */
    gap: 10px; /* 加点间隙更好看 */
}

/* 使用 grid-area 属性将项目分配到对应的区域 (后面会详细讲 grid-area) */
.area-header { grid-area: header; background-color: #16a085; }
.area-nav    { grid-area: nav;    background-color: #27ae60; }
.area-main   { grid-area: main;   background-color: #2980b9; }
.area-sidebar{ grid-area: sidebar;background-color: #8e44ad; }
.area-footer { grid-area: footer; background-color: #2c3e50; }
</style>

<h3>3.1 使用 `.` 表示空单元格</h3>
<div class="grid-container template-areas-dot">
    <div class="grid-item item-1 area-a">A</div>
    <div class="grid-item item-2 area-b">B</div>
    <div class="grid-item item-3 area-c">C</div>
</div>
<style>
.template-areas-dot {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 100px);
    grid-template-areas:
        "a . b"   /* 第1行:A 在第1列,第2列空,B 在第3列 */
        "a c c";  /* 第2行:A 在第1列,C 横跨第2、3列 */
    gap: 5px;
}
.area-a { grid-area: a; }
.area-b { grid-area: b; }
.area-c { grid-area: c; }
</style>

4. grid-template

grid-template-rows, grid-template-columns, 和 grid-template-areas 的简写属性。

语法比较复杂,通常是先定义 grid-template-areas,然后在每行字符串旁边加上行高定义,最后在末尾加上 / 和列宽定义。

xml 复制代码
<!-- grid-template 示例 -->
<h2>4. grid-template (简写)</h2>
<div class="grid-container template-shorthand">
    <header class="grid-item item-1 area-header-sh">Header</header>
    <main class="grid-item item-3 area-main-sh">Main</main>
    <footer class="grid-item item-5 area-footer-sh">Footer</footer>
</div>
<style>
.template-shorthand {
    display: grid;
    height: 300px;
    gap: 10px;
    /* 简写形式 */
    grid-template:
        [row1-start] "header header" auto     [row1-end] /* 第1行: 区域"header", 高度auto */
        [row2-start] "main   main"   1fr      [row2-end] /* 第2行: 区域"main", 高度1fr */
        [row3-start] "footer footer" 50px     [row3-end] /* 第3行: 区域"footer", 高度50px */
        /            1fr      1fr;                      /* 列宽定义: 两列,每列1fr */
        /* 注意:行名 [row-name] 是可选的 */
        /* 格式: [row-name]? "areas" row-size? [row-name]? ... / col-sizes */
}
/* 分配区域 */
.area-header-sh { grid-area: header; background-color: #1abc9c;}
.area-main-sh   { grid-area: main;   background-color: #3498db;}
.area-footer-sh { grid-area: footer; background-color: #95a5a6;}
</style>

5. grid-column-gapgrid-row-gap (以及 gap / grid-gap)

定义网格线之间的间隙(Gutter)。

  • grid-column-gap: 定义列间隙。
  • grid-row-gap: 定义行间隙。
  • grid-gap: grid-row-gapgrid-column-gap 的简写。grid-gap: <row-gap> <column-gap>; 如果只提供一个值,则行列间隙相同。
  • gap : 最新的标准写法,是 grid-gap 的别名,也适用于 Flexbox。推荐使用 gapgap: <row-gap> <column-gap>;
xml 复制代码
<!-- gap 示例 -->
<h2>5. gap / grid-gap (间隙)</h2>
<div class="grid-container gap-example">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
    <div class="grid-item item-5">5</div>
    <div class="grid-item item-6">6</div>
</div>
<style>
.gap-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, 100px);

    /* 老语法 */
    /* grid-row-gap: 20px; */
    /* grid-column-gap: 10px; */
    /* grid-gap: 20px 10px; */ /* row-gap column-gap */
    /* grid-gap: 15px; */ /* row-gap 和 column-gap 都是 15px */

    /* 新语法 (推荐) */
    /* row-gap: 20px; */
    /* column-gap: 10px; */
    gap: 20px 10px; /* row-gap column-gap */
    /* gap: 15px; */ /* row-gap 和 column-gap 都是 15px */
}
</style>

6. justify-items

定义网格项目在其单元格内部沿**行轴(内联轴/水平方向)**的对齐方式。应用于所有网格项目。

  • start: 对齐到单元格的起始边缘。
  • end: 对齐到单元格的结束边缘。
  • center: 对齐到单元格的中心。
  • stretch (默认值): 项目填充整个单元格的宽度。
xml 复制代码
<!-- justify-items 示例 -->
<h2>6. justify-items (项目水平对齐)</h2>
<div class="grid-container justify-items-example">
    <div class="grid-item item-1">Start</div>
    <div class="grid-item item-2">End</div>
    <div class="grid-item item-3">Center</div>
    <div class="grid-item item-4">Stretch (Default)</div>
</div>
<style>
.justify-items-example {
    display: grid;
    grid-template-columns: repeat(4, 1fr); /* 4列,每列宽度相同 */
    grid-template-rows: 100px; /* 1行,高度100px */
    gap: 10px;

    /* 设置不同的 justify-items 值 */
    /* justify-items: start; */
    /* justify-items: end; */
    /* justify-items: center; */
    justify-items: stretch; /* 默认值 */

    /* 为了演示效果,我们给每个 item 单独设置 (通常是在容器上设置一个值) */
    /* 这里我们用 justify-self 来覆盖演示 */
}
.justify-items-example .item-1 { justify-self: start; } /* 覆盖容器设置 */
.justify-items-example .item-2 { justify-self: end; }   /* 覆盖容器设置 */
.justify-items-example .item-3 { justify-self: center; } /* 覆盖容器设置 */
.justify-items-example .item-4 { justify-self: stretch; }/* 覆盖容器设置 (默认) */

/* 为了让非 stretch 生效,项目需要有固有宽度或不被拉伸 */
/* 在这里,默认情况下项目会拉伸,所以 start/end/center 看起来像是有外边距 */
/* 如果项目设置了宽度,效果更明显 */
.justify-items-example .grid-item {
     width: 80px; /* 给项目一个固定宽度,这样对齐效果更清晰 */
     /* 注意:设置了 width 后,stretch 也会表现得像 start,因为它无法拉伸 */
     /* 为了演示 stretch,我们移除第四个项目的宽度 */
}
.justify-items-example .item-4 {
    width: auto; /* 移除宽度,允许 stretch 生效 */
}

</style>

7. align-items

定义网格项目在其单元格内部沿**列轴(块轴/垂直方向)**的对齐方式。应用于所有网格项目。

  • start: 对齐到单元格的顶部边缘。
  • end: 对齐到单元格的底部边缘。
  • center: 对齐到单元格的垂直中心。
  • stretch (默认值): 项目填充整个单元格的高度。
  • baseline: 对齐到项目内容的基线。
css 复制代码
<!-- align-items 示例 -->
<h2>7. align-items (项目垂直对齐)</h2>
<div class="grid-container align-items-example">
    <div class="grid-item item-1" style="font-size: 1em; height: auto;">Start<br>Line 2</div>
    <div class="grid-item item-2" style="font-size: 1.5em; height: auto;">End</div>
    <div class="grid-item item-3" style="font-size: 1em; height: auto;">Center</div>
    <div class="grid-item item-4" style="font-size: 1.2em;">Stretch (Default)</div>
    <div class="grid-item item-5" style="font-size: 2em; height: auto;">Baseline</div>
    <div class="grid-item item-6" style="font-size: 1em; height: auto;">Baseline Ref</div>
</div>
<style>
.align-items-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 150px 150px; /* 行高设大一点方便观察 */
    gap: 10px;

    /* 设置不同的 align-items 值 */
    /* align-items: start; */
    /* align-items: end; */
    /* align-items: center; */
    /* align-items: stretch; */ /* 默认值 */
    align-items: baseline; /* 演示 baseline */

    /* 为了演示效果,我们给每个 item 单独设置 (通常是在容器上设置一个值) */
    /* 这里我们用 align-self 来覆盖演示 */
    /* 注意:要使非 stretch 生效,项目通常需要有固有高度或设置 height: auto */
}
.align-items-example .item-1 { align-self: start; }
.align-items-example .item-2 { align-self: end; }
.align-items-example .item-3 { align-self: center; }
.align-items-example .item-4 { align-self: stretch; height: auto; /* 允许拉伸 */}
.align-items-example .item-5 { align-self: baseline; } /* 参与基线对齐 */
.align-items-example .item-6 { align-self: baseline; } /* 参与基线对齐 */

</style>

8. place-items

align-itemsjustify-items 的简写。

  • place-items: <align-items> <justify-items>;
  • 如果只提供一个值,则 align-itemsjustify-items 都使用该值。
  • 例如 place-items: center; 等同于 align-items: center; justify-items: center;
  • 例如 place-items: start end; 等同于 align-items: start; justify-items: end;
xml 复制代码
<!-- place-items 示例 -->
<h2>8. place-items (项目对齐简写)</h2>
<div class="grid-container place-items-example">
    <div class="grid-item item-1">Center Center</div>
    <div class="grid-item item-2" style="width: 80px; height: 50px;">Start End</div>
    <div class="grid-item item-3" style="width: 100px; height: auto;">Stretch Center</div>
</div>
<style>
.place-items-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 150px;
    gap: 10px;

    /* place-items: center; */ /* align: center, justify: center */
    /* place-items: start end; */ /* align: start, justify: end */
    place-items: stretch center; /* align: stretch, justify: center */

    /* 为了演示,我们给项目设置了不同的宽高 */
}
/* 注意:place-items 设置的是容器级别所有项目的默认对齐方式 */
/* 可以通过 align-self / justify-self / place-self 在项目级别覆盖 */
</style>

9. justify-content

当网格的总宽度小于网格容器的宽度时,定义网格轨道(作为一个整体)在容器内沿**行轴(水平方向)**的对齐方式。

  • start (默认值): 网格向容器的起始位置对齐。
  • end: 网格向容器的结束位置对齐。
  • center: 网格在容器中居中对齐。
  • stretch: 拉伸网格轨道以填满容器宽度(仅适用于 auto 尺寸的轨道)。
  • space-around: 每个网格轨道两侧分配相等的空间,容器边缘的空间是轨道之间空间的一半。
  • space-between: 第一个轨道贴近容器起始边缘,最后一个轨道贴近容器结束边缘,剩余空间平均分配到轨道之间。
  • space-evenly: 每个网格轨道之间以及轨道与容器边缘之间的空间都相等。
xml 复制代码
<!-- justify-content 示例 -->
<h2>9. justify-content (网格水平对齐)</h2>
<p>需要网格总宽度小于容器宽度才能看到效果。</p>
<div class="grid-container justify-content-example">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
</div>
<style>
.justify-content-example {
    display: grid;
    width: 600px; /* 容器宽度 */
    height: 150px;
    grid-template-columns: 100px 100px 100px; /* 网格总宽度 300px + gap */
    grid-template-rows: 80px;
    gap: 10px; /* 间隙也会占用空间 (300 + 10 + 10 = 320px) */

    /* 尝试以下值 */
    /* justify-content: start; */ /* 默认 */
    /* justify-content: end; */
    /* justify-content: center; */
    /* justify-content: space-around; */
    /* justify-content: space-between; */
    justify-content: space-evenly;
    /* justify-content: stretch; */ /* 对固定宽度的列无效 */
}
</style>

10. align-content

当网格的总高度小于网格容器的高度时,定义网格轨道(作为一个整体)在容器内沿**列轴(垂直方向)**的对齐方式。

  • start (默认值): 网格向容器的顶部对齐。
  • end: 网格向容器的底部对齐。
  • center: 网格在容器中垂直居中对齐。
  • stretch: 拉伸网格轨道以填满容器高度(仅适用于 auto 尺寸的轨道)。
  • space-around: 每个网格轨道上下两侧分配相等的空间,容器边缘的空间是轨道之间空间的一半。
  • space-between: 第一行轨道贴近容器顶部边缘,最后一行轨道贴近容器底部边缘,剩余空间平均分配到轨道之间。
  • space-evenly: 每个网格轨道之间以及轨道与容器边缘之间的空间都相等。
xml 复制代码
<!-- align-content 示例 -->
<h2>10. align-content (网格垂直对齐)</h2>
<p>需要网格总高度小于容器高度才能看到效果。</p>
<div class="grid-container align-content-example">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
    <div class="grid-item item-5">5</div>
    <div class="grid-item item-6">6</div>
</div>
<style>
.align-content-example {
    display: grid;
    height: 400px; /* 容器高度 */
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 80px 80px; /* 网格总高度 160px + gap */
    gap: 10px; /* 间隙也会占用空间 (160 + 10 = 170px) */

    /* 尝试以下值 */
    /* align-content: start; */ /* 默认 */
    /* align-content: end; */
    /* align-content: center; */
    /* align-content: space-around; */
    /* align-content: space-between; */
    align-content: space-evenly;
    /* align-content: stretch; */ /* 对固定高度的行无效 */
}
</style>

11. place-content

align-contentjustify-content 的简写。

  • place-content: <align-content> <justify-content>;
  • 如果只提供一个值,则 align-contentjustify-content 都使用该值。
  • 例如 place-content: center; 等同于 align-content: center; justify-content: center;
  • 例如 place-content: space-between end; 等同于 align-content: space-between; justify-content: end;
xml 复制代码
<!-- place-content 示例 -->
<h2>11. place-content (网格对齐简写)</h2>
<div class="grid-container place-content-example">
    <div class="grid-item item-1">1</div>
    <div class="grid-item item-2">2</div>
    <div class="grid-item item-3">3</div>
    <div class="grid-item item-4">4</div>
</div>
<style>
.place-content-example {
    display: grid;
    width: 500px;  /* 容器尺寸大于网格尺寸 */
    height: 300px;
    grid-template-columns: 100px 100px; /* 网格宽度 200px + gap */
    grid-template-rows: 60px 60px;    /* 网格高度 120px + gap */
    gap: 10px; /* 宽度 210px, 高度 130px */

    /* place-content: center; */ /* 垂直居中 & 水平居中 */
    place-content: space-between end; /* 垂直 space-between & 水平 end */
    /* place-content: start space-evenly; */ /* 垂直 start & 水平 space-evenly */
}
</style>

12. grid-auto-columnsgrid-auto-rows

指定隐式创建的网格轨道(行或列)的大小。当网格项目放置在显式定义的网格范围之外时,就会创建隐式轨道。

xml 复制代码
<!-- grid-auto-columns / grid-auto-rows 示例 -->
<h2>12. grid-auto-columns / grid-auto-rows</h2>
<div class="grid-container auto-tracks-example">
    <div class="grid-item item-1">1 (Explicit)</div>
    <div class="grid-item item-2">2 (Explicit)</div>
    <div class="grid-item item-3" style="grid-column: 3;">3 (Implicit Col)</div>
    <div class="grid-item item-4" style="grid-row: 3;">4 (Implicit Row)</div>
    <div class="grid-item item-5" style="grid-column: 4; grid-row: 4;">5 (Implicit Col & Row)</div>
</div>
<style>
.auto-tracks-example {
    display: grid;
    /* 显式定义 2x2 网格 */
    grid-template-columns: 100px 100px;
    grid-template-rows: 80px 80px;
    gap: 5px;

    /* 定义隐式创建的列的宽度 */
    grid-auto-columns: 60px; /* 比如第3, 4列创建时宽度为60px */

    /* 定义隐式创建的行的高度 */
    grid-auto-rows: 40px; /* 比如第3, 4行创建时高度为40px */
}
</style>

13. grid-auto-flow

控制没有明确放置位置的网格项目(自动放置的项目)如何流入网格。

  • row (默认值): 自动放置的项目按顺序填充每一行,必要时添加新行。
  • column: 自动放置的项目按顺序填充每一列,必要时添加新列。
  • dense: "密集"打包算法。如果后面出现了较小的项目,它会尝试填补网格中较早出现的空白,可能导致项目顺序看起来被打乱,但布局更紧凑。
xml 复制代码
<!-- grid-auto-flow 示例 -->
<h2>13. grid-auto-flow</h2>

<h3>13.1 auto-flow: row (默认)</h3>
<div class="grid-container autoflow-row-example">
    <div class="grid-item item-1" style="grid-column: 1 / 3;">1 (Span 2 cols)</div>
    <div class="grid-item item-2">2 (Auto)</div>
    <div class="grid-item item-3">3 (Auto)</div>
    <div class="grid-item item-4">4 (Auto)</div>
</div>
<style>
.autoflow-row-example {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-template-rows: repeat(2, 80px);
    grid-auto-flow: row; /* 默认值,按行填充 */
    gap: 5px;
    /* 结果: */
    /* Item 1 占据 (1,1) 和 (1,2) */
    /* Item 2 放在 (1,3) */
    /* Item 3 放在 (2,1) */
    /* Item 4 放在 (2,2) */
}
</style>

<h3>13.2 auto-flow: column</h3>
<div class="grid-container autoflow-column-example">
    <div class="grid-item item-1" style="grid-row: 1 / 3;">1 (Span 2 rows)</div>
    <div class="grid-item item-2">2 (Auto)</div>
    <div class="grid-item item-3">3 (Auto)</div>
    <div class="grid-item item-4">4 (Auto)</div>
</div>
<style>
.autoflow-column-example {
    display: grid;
    grid-template-columns: repeat(2, 100px);
    grid-template-rows: repeat(3, 80px);
    grid-auto-flow: column; /* 按列填充 */
    gap: 5px;
    /* 结果: */
    /* Item 1 占据 (1,1) 和 (2,1) */
    /* Item 2 放在 (3,1) */
    /* Item 3 放在 (1,2) */
    /* Item 4 放在 (2,2) */
}
</style>

<h3>13.3 auto-flow: dense</h3>
<div class="grid-container autoflow-dense-example">
    <div class="grid-item item-1" style="grid-column: span 2;">1 (Span 2 cols)</div>
    <div class="grid-item item-2">2 (Auto)</div>
    <div class="grid-item item-3" style="grid-column: span 2;">3 (Span 2 cols)</div>
    <div class="grid-item item-4">4 (Auto)</div>
    <div class="grid-item item-5">5 (Auto)</div>
</div>
<style>
.autoflow-dense-example {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-auto-rows: 80px; /* 让自动行有高度 */
    grid-auto-flow: row dense; /* 使用密集填充 */
    gap: 5px;
    /* 结果 (对比没有 dense 的情况): */
    /* Item 1 占据 (1,1) (1,2) */
    /* Item 2 占据 (1,3) */
    /* Item 3 占据 (2,1) (2,2) */
    /* Item 4 发现第一行 (1,3) 被 Item 2 占了,但第二行 (2,3) 是空的,于是填充 (2,3) */
    /* Item 5 填充 (3,1) */
    /* 如果没有 dense: Item 4 会在 (3,1), Item 5 会在 (3,2),留下 (2,3) 空白 */
}
</style>

14. grid

所有网格属性的超级简写。语法非常复杂,不常用,因为它可读性较差。它能同时设置显式网格属性 (grid-template-*)、隐式网格属性 (grid-auto-*) 和 grid-auto-flow

其复杂性超出了常规使用范畴,通常建议分别设置各个属性。如果你确实需要了解,可以查阅 MDN 文档关于 grid 简写属性的详细说明。


第二部分:网格项目 (Grid Item) 属性

这些属性应用在网格容器的直接子元素上。

1. grid-column-start, grid-column-end, grid-row-start, grid-row-end

定义网格项目在网格中的位置和跨度。

  • 可以接受数字(网格线编号,从 1 开始)。
  • 可以接受命名网格线。
  • 可以使用 span <number> 指定跨越多少个轨道。
  • 可以使用 span <name> 指定跨越到名为 <name> 的网格线。
  • -1 通常表示最后一条网格线。
xml 复制代码
<!-- grid-column/row-start/end 示例 -->
<h2>15. grid-column/row-start/end</h2>
<div class="grid-container item-placement-example">
    <div class="grid-item item-1 item-pos-1">1 (col 1-3, row 1)</div>
    <div class="grid-item item-2 item-pos-2">2 (col 1, row 2-4)</div>
    <div class="grid-item item-3 item-pos-3">3 (col 2 / span 2, row 3)</div>
    <div class="grid-item item-4 item-pos-4">4 (col -1, row 1)</div>
    <div class="grid-item item-5 item-pos-5">5 (col 2 / col-mid, row 2 / row-end)</div>
</div>
<style>
.item-placement-example {
    display: grid;
    grid-template-columns: [col1-start] 1fr [col2-start col-mid] 1fr [col3-start] 1fr [col4-start col-end] 1fr [col5-start];
    grid-template-rows: [row1-start] 100px [row2-start] 100px [row3-start] 100px [row4-start row-end] 100px [row5-start];
    gap: 10px;
}

.item-pos-1 {
    /* 从第 1 条列线开始,到第 3 条列线结束 (跨越第1、2列) */
    grid-column-start: 1;
    grid-column-end: 3; /* 不包含第3条线本身,所以是第1、2列 */
    /* grid-column-end: span 2; */ /* 等效:从start开始跨越2列 */
    /* 行位置默认是 auto,会放在第一个可用行 */
    grid-row-start: 1;
    /* grid-row-end: 2; */ /* 等效 */
}

.item-pos-2 {
    /* 从第 1 条列线开始 */
    grid-column-start: 1;
    /* 从第 2 条行线开始,到第 4 条行线结束 (跨越第2、3行) */
    grid-row-start: 2;
    grid-row-end: 4; /* 不包含第4条线,所以是第2、3行 */
    /* grid-row-end: span 2; */ /* 等效 */
}

.item-pos-3 {
    /* 从第 2 条列线开始,跨越 2 列 (即第2、3列) */
    grid-column-start: 2;
    grid-column-end: span 2;
    /* 从第 3 条行线开始 */
    grid-row-start: 3;
}

.item-pos-4 {
    /* 放在最后一列 (使用负数索引) */
    /* grid-column-start: 4; */ /* 等效于这个4列网格 */
    grid-column-start: -1; /* 最后一条列线之前,即最后一列 */
    grid-column-end: -1; /* 不好理解,通常用 start 或 span */
    /* 推荐写法: */
    grid-column-start: 4;
    grid-column-end: 5; /* 或者 grid-column-end: span 1; */
    /* 或者 grid-column: 4 / 5; */
    /* 或者 grid-column: -1; */ /* 简写,表示最后一列 */

    grid-row-start: 1;
}

.item-pos-5 {
    /* 使用命名网格线 */
    grid-column-start: col2-start; /* 或 col-mid */
    grid-column-end: col-end; /* 到名为 col-end 的线结束 (跨越第2, 3, 4列) */
    grid-row-start: row2-start;
    grid-row-end: row-end; /* 到名为 row-end 的线结束 (跨越第2, 3行) */
}
</style>

2. grid-columngrid-row

分别是 grid-column-start / grid-column-endgrid-row-start / grid-row-end 的简写。

  • grid-column: <start-line> / <end-line>;
  • grid-row: <start-line> / <end-line>;
  • 如果只提供一个值,则 end-line 默认为 autospan 1
  • grid-column: 2 / 4; (占据第 2、3 列)
  • grid-column: 2 / span 3; (从第 2 列开始,跨越 3 列,即第 2、3、4 列)
  • grid-column: span 2; (跨越 2 列,起始位置自动)
  • grid-column: 3; (占据第 3 列)
  • grid-column: main-start / main-end; (使用命名线)
xml 复制代码
<!-- grid-column / grid-row 简写示例 -->
<h2>16. grid-column / grid-row (简写)</h2>
<div class="grid-container item-shorthand-example">
    <div class="grid-item item-1 item-sh-1">1 (col 2 / 4, row 1 / 3)</div>
    <div class="grid-item item-2 item-sh-2">2 (col 1, row 3 / span 2)</div>
    <div class="grid-item item-3 item-sh-3">3 (col span 2 / -1, row 4)</div>
</div>
<style>
.item-shorthand-example {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(4, 80px);
    gap: 10px;
}

.item-sh-1 {
    /* 列:从第2条线到第4条线 (第2、3列) */
    /* 行:从第1条线到第3条线 (第1、2行) */
    grid-column: 2 / 4;
    grid-row: 1 / 3;
}

.item-sh-2 {
    /* 列:第1列 (第1条线到第2条线) */
    grid-column: 1; /* 等同于 1 / 2 */
    /* 行:从第3条线开始,跨越2行 (第3、4行) */
    grid-row: 3 / span 2; /* 等同于 3 / 5 */
}

.item-sh-3 {
    /* 列:从自动位置开始跨越2列,并确保结束在最后一条线之前 (-1) */
    /* 这个例子有点复杂:跨越2列,并且它的结束线是 col-end(-1) */
    /* 假设自动放在第3列,跨2列会到第5条线,但结束线是-1(第5条),所以是第3、4列 */
    /* 如果自动放在第1列,跨2列到第3条线,结束线是-1(第5条),所以还是第1、2列 */
    /* 更清晰的写法可能是明确指定 start/end */
    /* 这里我们简化理解:放在最后两列 */
    grid-column: 3 / span 2; /* 放在第3、4列 */
    /* grid-column: span 2 / -1; */ /* 尝试让它在最后两列 */

    /* 行:第4行 */
    grid-row: 4; /* 等同于 4 / 5 */
}
</style>

3. grid-area

可以将网格项目分配到一个由 grid-template-areas 定义的命名区域,或者作为 grid-row-start, grid-column-start, grid-row-end, grid-column-end 的简写。

  • 分配到命名区域 : grid-area: <name>; (这个 <name> 必须在 grid-template-areas 中定义过)

  • 作为位置简写 : grid-area: <row-start> / <column-start> / <row-end> / <column-end>;

    • 可以使用数字、命名线或 span
xml 复制代码
<!-- grid-area 示例 -->
<h2>17. grid-area</h2>

<h3>17.1 分配到命名区域</h3>
<div class="grid-container area-assign-example">
    <div class="grid-item item-1 ga-header">Header</div>
    <div class="grid-item item-2 ga-main">Main</div>
    <div class="grid-item item-3 ga-footer">Footer</div>
</div>
<style>
.area-assign-example {
    display: grid;
    height: 250px;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
        "head head"
        "main main"
        "foot foot";
    gap: 5px;
}
.ga-header { grid-area: head; background-color: #f39c12; }
.ga-main   { grid-area: main; background-color: #16a085; }
.ga-footer { grid-area: foot; background-color: #7f8c8d; }
</style>

<h3>17.2 作为位置简写</h3>
<div class="grid-container area-shorthand-example">
    <div class="grid-item item-1 ga-pos-1">1</div>
    <div class="grid-item item-2 ga-pos-2">2</div>
</div>
<style>
.area-shorthand-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 80px);
    gap: 5px;
}
.ga-pos-1 {
    /* row-start / column-start / row-end / column-end */
    /* 占据第1行、第1列 到 第2行、第3列 的区域 (即第1行,第1、2列) */
    grid-area: 1 / 1 / 2 / 3;
    background-color: #3498db;
}
.ga-pos-2 {
    /* 占据第2行、第2列 到 第4行(不存在,即最后一行)、第4列(不存在,即最后一列) 的区域 */
    /* 即第2、3行,第2、3列 */
    grid-area: 2 / 2 / 4 / 4;
    /* 等同于: */
    /* grid-row-start: 2; */
    /* grid-column-start: 2; */
    /* grid-row-end: 4; */
    /* grid-column-end: 4; */
    background-color: #e74c3c;
}
</style>

4. justify-self

覆盖容器的 justify-items 设置,单独定义某个网格项目在其单元格内沿**行轴(水平方向)**的对齐方式。

  • start: 对齐到单元格的起始边缘。
  • end: 对齐到单元格的结束边缘。
  • center: 对齐到单元格的中心。
  • stretch (默认值,或继承自 justify-items): 项目填充整个单元格的宽度。
  • auto: 继承容器的 justify-items 值。
xml 复制代码
<!-- justify-self 示例 -->
<h2>18. justify-self (单个项目水平对齐)</h2>
<div class="grid-container justify-self-example">
    <div class="grid-item item-1 js-start">Start</div>
    <div class="grid-item item-2 js-end">End</div>
    <div class="grid-item item-3 js-center">Center</div>
    <div class="grid-item item-4 js-stretch">Stretch</div>
    <div class="grid-item item-5 js-auto">Auto (Inherits Center)</div>
</div>
<style>
.justify-self-example {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: 100px;
    gap: 10px;
    /* 容器设置 justify-items 为 center */
    justify-items: center;
}

/* 覆盖容器的设置 */
.js-start { justify-self: start; width: auto; /* 需要auto才能看到效果 */}
.js-end   { justify-self: end; width: auto; }
.js-center{ justify-self: center; width: auto; } /* 与容器设置相同 */
.js-stretch{ justify-self: stretch; } /* 覆盖 center */
.js-auto  { justify-self: auto; width: auto; } /* 继承容器的 center */

/* 为了让非 stretch 生效,项目需要有固有宽度或不被拉伸 */
/* 如果项目设置了 width: auto; 则对齐效果更明显 */
</style>

5. align-self

覆盖容器的 align-items 设置,单独定义某个网格项目在其单元格内沿**列轴(垂直方向)**的对齐方式。

  • start: 对齐到单元格的顶部边缘。
  • end: 对齐到单元格的底部边缘。
  • center: 对齐到单元格的垂直中心。
  • stretch (默认值,或继承自 align-items): 项目填充整个单元格的高度。
  • baseline: 对齐到项目内容的基线。
  • auto: 继承容器的 align-items 值。
xml 复制代码
<!-- align-self 示例 -->
<h2>19. align-self (单个项目垂直对齐)</h2>
<div class="grid-container align-self-example">
    <div class="grid-item item-1 as-start">Start</div>
    <div class="grid-item item-2 as-end">End</div>
    <div class="grid-item item-3 as-center">Center</div>
    <div class="grid-item item-4 as-stretch">Stretch</div>
    <div class="grid-item item-5 as-baseline" style="font-size: 2em;">Baseline</div>
    <div class="grid-item item-6 as-auto">Auto (Inherits Center)</div>
</div>
<style>
.align-self-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 150px 150px; /* 行高设大一点 */
    gap: 10px;
    /* 容器设置 align-items 为 center */
    align-items: center;
}

/* 覆盖容器的设置 */
.as-start    { align-self: start; height: auto; /* 需要auto才能看到效果 */ }
.as-end      { align-self: end; height: auto; }
.as-center   { align-self: center; height: auto; } /* 与容器设置相同 */
.as-stretch  { align-self: stretch; } /* 覆盖 center */
.as-baseline { align-self: baseline; height: auto; }
.as-auto     { align-self: auto; height: auto; } /* 继承容器的 center */

/* 为了让非 stretch 生效,项目通常需要有固有高度或设置 height: auto */
</style>

6. place-self

align-selfjustify-self 的简写。

  • place-self: <align-self> <justify-self>;
  • 如果只提供一个值,则 align-selfjustify-self 都使用该值。
  • 例如 place-self: center; 等同于 align-self: center; justify-self: center;
  • 例如 place-self: start end; 等同于 align-self: start; justify-self: end;
xml 复制代码
<!-- place-self 示例 -->
<h2>20. place-self (单个项目对齐简写)</h2>
<div class="grid-container place-self-example">
    <div class="grid-item item-1 ps-center">Center Both</div>
    <div class="grid-item item-2 ps-start-end">Start End</div>
    <div class="grid-item item-3 ps-stretch-center">Stretch Center</div>
</div>
<style>
.place-self-example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 150px;
    gap: 10px;
    /* 容器可以有自己的默认对齐,比如 */
    place-items: stretch stretch;
}

.ps-center {
    place-self: center; /* align: center, justify: center */
    width: 80px; height: 50px; /* 给定尺寸以观察效果 */
}
.ps-start-end {
    place-self: start end; /* align: start, justify: end */
    width: 80px; height: 50px;
}
.ps-stretch-center {
    place-self: stretch center; /* align: stretch, justify: center */
    width: 80px; /* 高度会拉伸,宽度居中 */
}
</style>

总结与补充

  • 显式网格 vs 隐式网格 : grid-template-* 定义的是显式网格。当项目被放置在显式网格之外,或者使用 grid-auto-flow 自动放置时,可能会创建隐式网格轨道,其大小由 grid-auto-columnsgrid-auto-rows 控制。
  • fr 单位的计算 : fr 单位分配的是可用空间 。可用空间是指容器尺寸减去所有非灵活轨道(如 px, %, auto 计算后的尺寸)和间隙 gap 后的剩余空间。
  • minmax() 的威力 : 结合 frrepeat(auto-fit, ...)repeat(auto-fill, ...) 可以创建非常灵活和响应式的布局。例如 repeat(auto-fit, minmax(200px, 1fr)) 表示创建尽可能多的列,每列最小 200px,并且允许它们伸展以填充可用空间。
  • Subgrid (子网格) : 这是一个较新的特性 (display: subgrid),允许嵌套的网格容器继承其父网格容器的轨道定义。这对于需要内部元素与外部网格对齐的复杂布局非常有用。浏览器支持度正在逐步提高。
  • 性能: Grid 布局通常性能良好,浏览器对其进行了优化。
  • 兼容性 : 主流现代浏览器对 CSS Grid Layout 的支持已经非常好。对于旧版浏览器(如 IE11),需要使用 -ms- 前缀,并且支持的是旧版本的规范,功能有限且语法不同。
相关推荐
高木的小天才2 分钟前
鸿蒙中的并发线程间通信、线程间通信对象
前端·华为·typescript·harmonyos
Danta1 小时前
百度网盘一面值得look:我有点难受🤧🤧
前端·javascript·面试
OpenTiny社区1 小时前
TinyVue v3.22.0 正式发布:深色模式上线!集成 UnoCSS 图标库!TypeScript 类型支持全面升级!
前端·vue.js·开源
dwqqw1 小时前
opencv图像库编程
前端·webpack·node.js
Captaincc2 小时前
为什么MCP火爆技术圈,普通用户却感觉不到?
前端·ai编程
阿虎儿3 小时前
MCP
前端
毕小宝3 小时前
编写一个网页版的音频播放器,AI 加持,So easy!
前端·javascript
万水千山走遍TML3 小时前
JavaScript性能优化
开发语言·前端·javascript·性能优化·js·js性能
Aphasia3113 小时前
react必备JS知识点(一)——判断this指向👆🏻
前端·javascript·react.js
会飞的鱼先生3 小时前
vue3中slot(插槽)的详细使用
前端·javascript·vue.js