pin_drop当前位置:知识文库 ❯ 图文

布局结构:HTML Grid布局 - 完整教程与代码示例


一、核心概念

Grid的基本模型

代码示例

Grid容器
+---+---+---+---+---+---+
|   |   |   |   |   |   |  <-- 网格行(Grid Row)
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+
  ^   ^   ^   ^   ^   ^
  网格列(Grid Column)

网格线:1  2  3  4  5  6  7
网格轨道:两个相邻网格线之间的空间
网格单元:行和列的交叉点
网格区域:由多个网格单元组成的矩形区域

Grid术语

术语 说明
Grid Container 设置display:grid的元素
Grid Item Grid容器的直接子元素
Grid Line 构成网格结构的分界线
Grid Track 两条相邻网格线之间的空间(行或列)
Grid Cell 行和列交叉形成的最小单元
Grid Area 由多个网格单元组成的矩形区域
Grid Gap 网格轨道之间的间距

二、语法与用法

Grid容器属性

1. 定义Grid容器

代码示例

.grid-container {
    display: grid;
    display: inline-grid;
}

2. 定义行列

代码示例

.grid-container {
    /* 固定列数 */
    grid-template-columns: 200px 200px 200px;
    grid-template-columns: repeat(3, 200px);

    /* 等分列 */
    grid-template-columns: repeat(3, 1fr);

    /* 混合 */
    grid-template-columns: 250px 1fr 1fr;

    /* 自适应 */
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

    /* 行定义 */
    grid-template-rows: auto 1fr auto;
    grid-template-rows: 100px repeat(3, 1fr) 80px;
}

3. 网格间距

代码示例

.grid-container {
    gap: 20px;           /* 行列间距 */
    row-gap: 20px;       /* 行间距 */
    column-gap: 30px;    /* 列间距 */
}

4. 网格区域

代码示例

.grid-container {
    grid-template-areas:
        "header header header"
        "sidebar main main"
        "footer footer footer";
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }

/* 空白区域用.表示 */
grid-template-areas:
    "header header header"
    "sidebar .    main"
    "footer footer footer";

5. 对齐属性

代码示例

.grid-container {
    /* 所有项目在单元格内的水平对齐 */
    justify-items: start | end | center | stretch;

    /* 所有项目在单元格内的垂直对齐 */
    align-items: start | end | center | stretch;

    /* 网格在容器内的水平对齐 */
    justify-content: start | end | center | stretch | space-between | space-around;

    /* 网格在容器内的垂直对齐 */
    align-content: start | end | center | stretch | space-between | space-around;
}

Grid项目属性

代码示例

.grid-item {
    /* 基于网格线定位 */
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;

    /* 简写 */
    grid-column: 1 / 3;        /* 从第1条线到第3条线 */
    grid-column: 1 / span 2;   /* 从第1条线开始跨2列 */
    grid-column: span 2;       /* 跨2列 */
    grid-row: 1 / 3;

    /* 区域定位 */
    grid-area: header;
    grid-area: 1 / 1 / 3 / 3;  /* row-start / col-start / row-end / col-end */

    /* 单个项目对齐 */
    justify-self: start | end | center | stretch;
    align-self: start | end | center | stretch;

    /* 排列顺序 */
    order: 0;
}

三、代码示例

示例1:Grid布局属性演示

以下示例展示了Grid的各种属性,包括等分列、固定+弹性列、自适应列、网格区域布局和跨列跨行。

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid布局属性演示</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: "Microsoft YaHei", sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }
        h2 { color: #2c3e50; margin-bottom: 15px; font-size: 1.1rem; }
        .section {
            background: white;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        .desc { color: #666; font-size: 13px; margin-bottom: 10px; }

        .grid-demo {
            display: grid;
            gap: 10px;
            padding: 10px;
            background: #ecf0f1;
            border-radius: 6px;
        }
        .grid-demo .item {
            background: #3498db;
            color: white;
            padding: 15px;
            border-radius: 4px;
            text-align: center;
            font-size: 14px;
        }

        /* 等分列 */
        .equal-cols { grid-template-columns: repeat(3, 1fr); }

        /* 固定+弹性 */
        .mixed-cols { grid-template-columns: 200px 1fr 1fr; }

        /* 自适应列 */
        .auto-cols { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }

        /* 网格区域布局 */
        .area-layout {
            grid-template-areas:
                "header header header"
                "sidebar main main"
                "footer footer footer";
            grid-template-columns: 200px 1fr 1fr;
            grid-template-rows: 60px 1fr 50px;
            min-height: 300px;
        }
        .area-header { grid-area: header; background: #e74c3c; }
        .area-sidebar { grid-area: sidebar; background: #f39c12; }
        .area-main { grid-area: main; background: #27ae60; }
        .area-footer { grid-area: footer; background: #9b59b6; }

        /* 跨列跨行 */
        .span-demo {
            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(3, 60px);
        }
        .span-col2 { grid-column: span 2; background: #e74c3c !important; }
        .span-row2 { grid-row: span 2; background: #f39c12 !important; }
        .span-both { grid-column: span 2; grid-row: span 2; background: #1abc9c !important; }
    </style>
</head>
<body>
    <div class="section">
        <h2>1. 等分列 - repeat(3, 1fr)</h2>
        <div class="grid-demo equal-cols">
            <div class="item">1fr</div><div class="item">1fr</div><div class="item">1fr</div>
        </div>
    </div>

    <div class="section">
        <h2>2. 固定+弹性列 - 200px 1fr 1fr</h2>
        <div class="grid-demo mixed-cols">
            <div class="item">200px</div><div class="item">1fr</div><div class="item">1fr</div>
        </div>
    </div>

    <div class="section">
        <h2>3. 自适应列 - auto-fill + minmax</h2>
        <p class="desc">调整浏览器宽度查看列数自动变化</p>
        <div class="grid-demo auto-cols">
            <div class="item">1</div><div class="item">2</div><div class="item">3</div>
            <div class="item">4</div><div class="item">5</div><div class="item">6</div>
        </div>
    </div>

    <div class="section">
        <h2>4. 网格区域布局</h2>
        <div class="grid-demo area-layout">
            <div class="item area-header">Header</div>
            <div class="item area-sidebar">Sidebar</div>
            <div class="item area-main">Main</div>
            <div class="item area-footer">Footer</div>
        </div>
    </div>

    <div class="section">
        <h2>5. 跨列跨行</h2>
        <div class="grid-demo span-demo">
            <div class="item span-col2">跨2列</div>
            <div class="item">普通</div>
            <div class="item span-row2">跨2行</div>
            <div class="item">普通</div>
            <div class="item">普通</div>
            <div class="item span-both">跨2列2行</div>
            <div class="item">普通</div>
        </div>
    </div>
</body>
</html>

示例2:Grid实战页面布局

以下示例展示了如何使用Grid构建完整的仪表盘页面布局,包括统计卡片、数据网格和侧边栏。

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid实战页面布局</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: "Microsoft YaHei", sans-serif;
            background: #f0f2f5;
            color: #333;
        }

        /* Grid页面框架 */
        .page {
            display: grid;
            grid-template-areas:
                "header"
                "nav"
                "main"
                "footer";
            grid-template-rows: auto auto 1fr auto;
            min-height: 100vh;
        }

        .page-header {
            grid-area: header;
            background: #2c3e50;
            color: white;
            padding: 15px 30px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .page-header .logo { font-size: 1.5rem; font-weight: bold; }

        .page-nav {
            grid-area: nav;
            background: #34495e;
            padding: 0 30px;
        }
        .page-nav ul {
            display: flex;
            list-style: none;
            gap: 5px;
        }
        .page-nav a {
            color: #aaa;
            text-decoration: none;
            padding: 12px 18px;
            display: block;
            font-size: 14px;
            transition: color 0.3s, background 0.3s;
        }
        .page-nav a:hover, .page-nav a.active {
            color: white;
            background: rgba(255,255,255,0.1);
        }

        .page-main {
            grid-area: main;
            display: grid;
            grid-template-columns: 1fr 300px;
            gap: 20px;
            max-width: 1200px;
            margin: 20px auto;
            padding: 0 20px;
            width: 100%;
        }

        .content-area { display: grid; gap: 20px; }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
            gap: 15px;
        }
        .stat-card {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 1px 4px rgba(0,0,0,0.08);
            text-align: center;
        }
        .stat-card .number {
            font-size: 2rem;
            font-weight: bold;
            color: #3498db;
        }
        .stat-card .label {
            color: #999;
            font-size: 13px;
            margin-top: 5px;
        }

        .data-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 15px;
        }
        .data-card {
            background: white;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 1px 4px rgba(0,0,0,0.08);
        }
        .data-card .card-header {
            padding: 12px 15px;
            background: #3498db;
            color: white;
            font-weight: bold;
            font-size: 14px;
        }
        .data-card .card-body {
            padding: 15px;
            font-size: 13px;
            color: #666;
            line-height: 1.6;
        }

        .sidebar-area { display: grid; gap: 20px; align-content: start; }
        .widget {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 1px 4px rgba(0,0,0,0.08);
        }
        .widget h3 {
            color: #2c3e50;
            margin-bottom: 12px;
            font-size: 1rem;
            padding-bottom: 8px;
            border-bottom: 2px solid #3498db;
        }
        .widget ul { list-style: none; }
        .widget ul li {
            padding: 6px 0;
            border-bottom: 1px solid #f0f0f0;
            font-size: 13px;
        }
        .widget ul li:last-child { border-bottom: none; }
        .widget ul li a { color: #555; text-decoration: none; }

        .page-footer {
            grid-area: footer;
            background: #2c3e50;
            color: #aaa;
            text-align: center;
            padding: 15px;
            font-size: 13px;
        }

        @media (max-width: 768px) {
            .page-main { grid-template-columns: 1fr; }
            .page-nav ul { flex-wrap: wrap; }
        }
    </style>
</head>
<body>
    <div class="page">
        <header class="page-header">
            <div class="logo">GridDashboard</div>
        </header>
        <nav class="page-nav">
            <ul>
                <li><a href="#" class="active">仪表盘</a></li>
                <li><a href="#">数据</a></li>
                <li><a href="#">设置</a></li>
            </ul>
        </nav>
        <main class="page-main">
            <div class="content-area">
                <div class="stats-grid">
                    <div class="stat-card"><div class="number">1,234</div><div class="label">总用户</div></div>
                    <div class="stat-card"><div class="number" style="color:#27ae60;">567</div><div class="label">活跃用户</div></div>
                    <div class="stat-card"><div class="number" style="color:#e74c3c;">89</div><div class="label">新增用户</div></div>
                    <div class="stat-card"><div class="number" style="color:#f39c12;">45%</div><div class="label">转化率</div></div>
                </div>
                <div class="data-grid">
                    <div class="data-card"><div class="card-header">项目A</div><div class="card-body">进度:75%</div></div>
                    <div class="data-card"><div class="card-header" style="background:#27ae60;">项目B</div><div class="card-body">进度:90%</div></div>
                    <div class="data-card"><div class="card-header" style="background:#e74c3c;">项目C</div><div class="card-body">进度:30%</div></div>
                    <div class="data-card"><div class="card-header" style="background:#f39c12;">项目D</div><div class="card-body">进度:60%</div></div>
                </div>
            </div>
            <aside class="sidebar-area">
                <div class="widget"><h3>最近活动</h3><ul><li>用户张三登录</li><li>项目A更新</li></ul></div>
                <div class="widget"><h3>快捷操作</h3><ul><li>创建项目</li><li>导出报告</li></ul></div>
            </aside>
        </main>
        <footer class="page-footer"><p>Copyright 2026 GridDashboard</p></footer>
    </div>
</body>
</html>

四、浏览器兼容性

特性 Chrome Firefox Safari Edge IE
基本Grid 57+ 52+ 10.1+ 16+ 不支持
grid-gap 66+ 61+ 12+ 16+ 不支持
grid-template-areas 57+ 52+ 10.1+ 16+ 不支持
auto-fill/auto-fit 57+ 52+ 10.1+ 16+ 不支持
subgrid 75+ 69+ 16+ 79+ 不支持

五、注意事项与最佳实践

1. auto-fill vs auto-fit

代码示例

/* auto-fill: 创建尽可能多的列,空列保留空间 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

/* auto-fit: 创建尽可能多的列,空列折叠为0 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

2. fr单位的使用

代码示例

/* fr是Grid特有的单位,表示可用空间的比例 */
grid-template-columns: 1fr 2fr 1fr;  /* 1:2:1比例 */

/* fr与固定单位混合 */
grid-template-columns: 250px 1fr 1fr;  /* 第一列固定250px,其余等分 */

/* 注意:fr计算的是剩余空间 */
grid-template-columns: 1fr 1fr;  /* 各占50%的可用空间 */

3. 响应式Grid无需媒体查询

代码示例

/* 自动响应式网格 */
.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

4. Grid与Flexbox配合

代码示例

/* Grid做页面框架,Flexbox做组件内部 */
.page {
    display: grid;
    grid-template-columns: 250px 1fr;
}

.nav {
    display: flex;  /* 导航用Flex */
    flex-direction: column;
    gap: 5px;
}

六、代码规范示例

代码示例

/* ========================================
   Grid布局规范
   ======================================== */

/* 页面框架用Grid */
.page {
    display: grid;
    grid-template-areas:
        "header header"
        "sidebar main"
        "footer footer";
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto 1fr auto;
    min-height: 100vh;
    gap: 0;
}

/* 卡片网格用Grid自适应 */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

/* 固定列数用Grid */
.form-grid {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 12px 20px;
    align-items: center;
}

七、常见问题与解决方案

常见问题

Grid项目溢出容器怎么办?

解决方案:设置min-width: 0overflow: hidden,防止内容撑破网格单元。

auto-fill在小屏上项目太窄如何处理?

解决方案:使用min()限制最小宽度,如repeat(auto-fill, minmax(min(280px, 100%), 1fr))

网格区域名称拼写错误怎么避免?

确保grid-template-areas中的名称与grid-area完全匹配,大小写必须一致。


八、总结

CSS Grid是现代Web布局的强大工具,关键要点如下:

  • 二维布局:Grid同时控制行和列,是构建复杂页面框架的最佳选择

  • fr单位:Grid特有的弹性单位,按比例分配可用空间

  • 网格区域grid-template-areas让布局代码直观易读

  • 自适应列auto-fill/auto-fit + minmax实现无媒体查询的响应式

  • 与Flexbox互补:Grid做宏观框架,Flexbox做微观排列

  • subgrid:子网格让嵌套Grid对齐更简单

  • 命名网格线:使用命名网格线提高代码可读性


标签: CSS Grid 网格布局 二维布局 响应式网格 网格区域 CSS3

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 布局结构:HTML Flexbox布局 - 完整教程与代码示例 下一篇: 布局结构:HTML模板template - 完整教程与代码示例

poll相关推荐