5.1 Grid 布局简介

5.1.1 什么是 CSS Grid

CSS Grid 是一个二维布局系统,允许您同时在行和列两个维度上控制元素的位置。与 Flexbox 的一维布局不同,Grid 提供了更强大的布局能力。

5.1.2 Grid vs Flexbox

特性 Grid Flexbox
维度 二维(行+列) 一维(行或列)
适用场景 复杂布局、页面结构 组件内部布局
浏览器支持 现代浏览器 更广泛支持
学习曲线 较陡峭 相对简单

5.1.3 基本概念

  • Grid Container:设置了 display: grid 的父元素
  • Grid Item:Grid 容器的直接子元素
  • Grid Line:构成网格结构的分界线
  • Grid Track:两条相邻网格线之间的空间
  • Grid Cell:四条网格线围成的区域
  • Grid Area:由四条网格线围成的矩形区域

5.2 Grid 容器属性

5.2.1 创建 Grid 容器

<!-- 基础 Grid 容器 -->
<div class="grid">
    <div>项目 1</div>
    <div>项目 2</div>
    <div>项目 3</div>
</div>

<!-- 内联 Grid 容器 -->
<div class="inline-grid">
    <div>项目 1</div>
    <div>项目 2</div>
</div>

5.2.2 定义网格轨道

列轨道定义

<!-- 固定列宽 -->
<div class="grid grid-cols-3">
    <div class="bg-blue-100 p-4">列 1</div>
    <div class="bg-green-100 p-4">列 2</div>
    <div class="bg-red-100 p-4">列 3</div>
</div>

<!-- 不同列宽 -->
<div class="grid grid-cols-[200px_1fr_100px]">
    <div class="bg-blue-100 p-4">固定 200px</div>
    <div class="bg-green-100 p-4">弹性列</div>
    <div class="bg-red-100 p-4">固定 100px</div>
</div>

<!-- 重复模式 -->
<div class="grid grid-cols-[repeat(3,1fr)]">
    <div class="bg-blue-100 p-4">等宽 1</div>
    <div class="bg-green-100 p-4">等宽 2</div>
    <div class="bg-red-100 p-4">等宽 3</div>
</div>

行轨道定义

<!-- 固定行高 -->
<div class="grid grid-rows-3 h-96">
    <div class="bg-blue-100 p-4">行 1</div>
    <div class="bg-green-100 p-4">行 2</div>
    <div class="bg-red-100 p-4">行 3</div>
</div>

<!-- 不同行高 -->
<div class="grid grid-rows-[100px_1fr_50px] h-96">
    <div class="bg-blue-100 p-4">固定 100px</div>
    <div class="bg-green-100 p-4">弹性行</div>
    <div class="bg-red-100 p-4">固定 50px</div>
</div>

5.2.3 网格间距

<!-- 统一间距 -->
<div class="grid grid-cols-3 gap-4">
    <div class="bg-blue-100 p-4">项目 1</div>
    <div class="bg-green-100 p-4">项目 2</div>
    <div class="bg-red-100 p-4">项目 3</div>
</div>

<!-- 不同行列间距 -->
<div class="grid grid-cols-3 gap-x-4 gap-y-8">
    <div class="bg-blue-100 p-4">项目 1</div>
    <div class="bg-green-100 p-4">项目 2</div>
    <div class="bg-red-100 p-4">项目 3</div>
    <div class="bg-yellow-100 p-4">项目 4</div>
    <div class="bg-purple-100 p-4">项目 5</div>
    <div class="bg-pink-100 p-4">项目 6</div>
</div>

5.2.4 网格对齐

整体内容对齐

<!-- 水平对齐 -->
<div class="grid grid-cols-3 justify-items-center h-32">
    <div class="bg-blue-100 p-2">居中</div>
    <div class="bg-green-100 p-2">居中</div>
    <div class="bg-red-100 p-2">居中</div>
</div>

<!-- 垂直对齐 -->
<div class="grid grid-cols-3 align-items-center h-32">
    <div class="bg-blue-100 p-2">居中</div>
    <div class="bg-green-100 p-2">居中</div>
    <div class="bg-red-100 p-2">居中</div>
</div>

<!-- 同时对齐 -->
<div class="grid grid-cols-3 place-items-center h-32">
    <div class="bg-blue-100 p-2">居中</div>
    <div class="bg-green-100 p-2">居中</div>
    <div class="bg-red-100 p-2">居中</div>
</div>

网格容器对齐

<!-- 水平对齐网格 -->
<div class="grid grid-cols-3 justify-content-center w-full h-32 bg-gray-100">
    <div class="bg-blue-100 p-2">项目 1</div>
    <div class="bg-green-100 p-2">项目 2</div>
    <div class="bg-red-100 p-2">项目 3</div>
</div>

<!-- 垂直对齐网格 -->
<div class="grid grid-cols-3 align-content-center w-full h-64 bg-gray-100">
    <div class="bg-blue-100 p-2">项目 1</div>
    <div class="bg-green-100 p-2">项目 2</div>
    <div class="bg-red-100 p-2">项目 3</div>
</div>

5.3 Grid 项目属性

5.3.1 网格线定位

<div class="grid grid-cols-4 grid-rows-3 gap-2 h-64">
    <!-- 指定起始和结束列 -->
    <div class="bg-blue-100 p-2 col-start-1 col-end-3">跨越 2 列</div>
    
    <!-- 使用 span 语法 -->
    <div class="bg-green-100 p-2 col-span-2">跨越 2 列</div>
    
    <!-- 指定起始和结束行 -->
    <div class="bg-red-100 p-2 row-start-2 row-end-4">跨越 2 行</div>
    
    <!-- 同时跨越行和列 -->
    <div class="bg-yellow-100 p-2 col-span-2 row-span-2">跨越 2x2</div>
</div>

5.3.2 网格区域命名

<!-- 使用 CSS 自定义属性定义网格模板 -->
<div class="grid h-screen" style="
    grid-template-areas: 
        'header header header'
        'sidebar main main'
        'footer footer footer';
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 200px 1fr;
">
    <header class="bg-blue-100 p-4" style="grid-area: header;">头部</header>
    <aside class="bg-green-100 p-4" style="grid-area: sidebar;">侧边栏</aside>
    <main class="bg-white p-4" style="grid-area: main;">主内容</main>
    <footer class="bg-gray-100 p-4" style="grid-area: footer;">页脚</footer>
</div>

5.3.3 单个项目对齐

<div class="grid grid-cols-3 gap-4 h-32">
    <!-- 水平对齐 -->
    <div class="bg-blue-100 p-2 justify-self-start">左对齐</div>
    <div class="bg-green-100 p-2 justify-self-center">居中</div>
    <div class="bg-red-100 p-2 justify-self-end">右对齐</div>
    
    <!-- 垂直对齐 -->
    <div class="bg-yellow-100 p-2 align-self-start">顶部对齐</div>
    <div class="bg-purple-100 p-2 align-self-center">居中对齐</div>
    <div class="bg-pink-100 p-2 align-self-end">底部对齐</div>
    
    <!-- 同时对齐 -->
    <div class="bg-indigo-100 p-2 place-self-center">完全居中</div>
    <div class="bg-orange-100 p-2 place-self-start">左上角</div>
    <div class="bg-teal-100 p-2 place-self-end">右下角</div>
</div>

5.4 响应式 Grid 布局

5.4.1 响应式列数

<!-- 响应式网格 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
    <div class="bg-blue-100 p-4 rounded">项目 1</div>
    <div class="bg-green-100 p-4 rounded">项目 2</div>
    <div class="bg-red-100 p-4 rounded">项目 3</div>
    <div class="bg-yellow-100 p-4 rounded">项目 4</div>
    <div class="bg-purple-100 p-4 rounded">项目 5</div>
    <div class="bg-pink-100 p-4 rounded">项目 6</div>
    <div class="bg-indigo-100 p-4 rounded">项目 7</div>
    <div class="bg-orange-100 p-4 rounded">项目 8</div>
</div>

5.4.2 自适应网格

<!-- 自动填充网格 -->
<div class="grid gap-4" style="grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));">
    <div class="bg-blue-100 p-4 rounded">
        <h3 class="font-semibold mb-2">卡片 1</h3>
        <p class="text-gray-600">这是一个自适应的卡片布局</p>
    </div>
    <div class="bg-green-100 p-4 rounded">
        <h3 class="font-semibold mb-2">卡片 2</h3>
        <p class="text-gray-600">卡片会根据容器宽度自动调整</p>
    </div>
    <div class="bg-red-100 p-4 rounded">
        <h3 class="font-semibold mb-2">卡片 3</h3>
        <p class="text-gray-600">最小宽度 250px,最大宽度 1fr</p>
    </div>
    <div class="bg-yellow-100 p-4 rounded">
        <h3 class="font-semibold mb-2">卡片 4</h3>
        <p class="text-gray-600">非常适合响应式设计</p>
    </div>
</div>

5.4.3 响应式网格区域

<!-- 移动端布局 -->
<div class="grid gap-4 md:h-screen" style="
    grid-template-areas: 
        'header'
        'main'
        'sidebar'
        'footer';
    grid-template-rows: auto 1fr auto auto;
">
    <header class="bg-blue-100 p-4 rounded" style="grid-area: header;">头部</header>
    <main class="bg-white p-4 rounded border" style="grid-area: main;">主内容</main>
    <aside class="bg-green-100 p-4 rounded" style="grid-area: sidebar;">侧边栏</aside>
    <footer class="bg-gray-100 p-4 rounded" style="grid-area: footer;">页脚</footer>
</div>

<!-- 桌面端布局(使用媒体查询) -->
<style>
@media (min-width: 768px) {
    .responsive-grid {
        grid-template-areas: 
            'header header'
            'sidebar main'
            'footer footer';
        grid-template-rows: auto 1fr auto;
        grid-template-columns: 200px 1fr;
    }
}
</style>

5.5 常用 Grid 布局模式

5.5.1 圣杯布局

<div class="grid h-screen" style="
    grid-template-areas: 
        'header header header'
        'sidebar main aside'
        'footer footer footer';
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 200px 1fr 200px;
    gap: 1rem;
">
    <header class="bg-blue-600 text-white p-4 rounded" style="grid-area: header;">
        <h1 class="text-xl font-bold">网站标题</h1>
    </header>
    
    <nav class="bg-green-100 p-4 rounded" style="grid-area: sidebar;">
        <h2 class="font-semibold mb-4">导航菜单</h2>
        <ul class="space-y-2">
            <li><a href="#" class="text-blue-600 hover:underline">首页</a></li>
            <li><a href="#" class="text-blue-600 hover:underline">关于</a></li>
            <li><a href="#" class="text-blue-600 hover:underline">服务</a></li>
            <li><a href="#" class="text-blue-600 hover:underline">联系</a></li>
        </ul>
    </nav>
    
    <main class="bg-white p-4 rounded border" style="grid-area: main;">
        <h2 class="text-2xl font-bold mb-4">主要内容</h2>
        <p class="text-gray-600 mb-4">
            这里是页面的主要内容区域。使用 CSS Grid 可以轻松创建复杂的布局结构。
        </p>
        <p class="text-gray-600">
            Grid 布局提供了强大的二维布局能力,非常适合创建页面级别的布局。
        </p>
    </main>
    
    <aside class="bg-yellow-100 p-4 rounded" style="grid-area: aside;">
        <h2 class="font-semibold mb-4">侧边栏</h2>
        <div class="space-y-4">
            <div class="bg-white p-3 rounded border">
                <h3 class="font-medium mb-2">最新文章</h3>
                <p class="text-sm text-gray-600">文章标题示例</p>
            </div>
            <div class="bg-white p-3 rounded border">
                <h3 class="font-medium mb-2">热门标签</h3>
                <div class="flex flex-wrap gap-1">
                    <span class="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">CSS</span>
                    <span class="bg-green-100 text-green-800 px-2 py-1 rounded text-xs">Grid</span>
                    <span class="bg-red-100 text-red-800 px-2 py-1 rounded text-xs">布局</span>
                </div>
            </div>
        </div>
    </aside>
    
    <footer class="bg-gray-800 text-white p-4 rounded" style="grid-area: footer;">
        <p class="text-center">&copy; 2024 我的网站. 保留所有权利.</p>
    </footer>
</div>

5.5.2 卡片网格布局

<div class="grid gap-6" style="grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));">
    <!-- 卡片 1 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-blue-400 to-blue-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">产品设计</h3>
            <p class="text-gray-600 mb-4">
                创造出色的用户体验,从概念到实现的完整设计流程。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-blue-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
    
    <!-- 卡片 2 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-green-400 to-green-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">前端开发</h3>
            <p class="text-gray-600 mb-4">
                使用现代技术栈构建响应式和交互式的 Web 应用程序。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-green-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
    
    <!-- 卡片 3 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-purple-400 to-purple-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">数据分析</h3>
            <p class="text-gray-600 mb-4">
                通过数据驱动的洞察来优化业务决策和用户体验。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-purple-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
    
    <!-- 卡片 4 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-red-400 to-red-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">品牌策略</h3>
            <p class="text-gray-600 mb-4">
                建立强有力的品牌形象,在竞争激烈的市场中脱颖而出。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-red-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
    
    <!-- 卡片 5 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-yellow-400 to-yellow-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">移动应用</h3>
            <p class="text-gray-600 mb-4">
                开发原生和跨平台移动应用,提供卓越的移动体验。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-yellow-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
    
    <!-- 卡片 6 -->
    <div class="bg-white rounded-lg shadow-md overflow-hidden">
        <div class="h-48 bg-gradient-to-r from-indigo-400 to-indigo-600"></div>
        <div class="p-6">
            <h3 class="text-xl font-semibold mb-2">云服务</h3>
            <p class="text-gray-600 mb-4">
                构建可扩展的云基础设施,确保应用的高可用性和性能。
            </p>
            <div class="flex items-center justify-between">
                <span class="text-indigo-600 font-medium">了解更多</span>
                <svg class="w-5 h-5 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
                </svg>
            </div>
        </div>
    </div>
</div>

5.5.3 瀑布流布局

<div class="grid gap-4" style="grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-auto-rows: min-content;">
    <!-- 项目 1 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-32 bg-blue-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">短内容卡片</h3>
        <p class="text-gray-600 text-sm">这是一个较短的内容示例。</p>
    </div>
    
    <!-- 项目 2 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-48 bg-green-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">中等长度内容</h3>
        <p class="text-gray-600 text-sm mb-3">
            这是一个中等长度的内容示例,包含更多的文字描述和详细信息。
        </p>
        <p class="text-gray-600 text-sm">
            Grid 布局会自动调整每个项目的高度以适应内容。
        </p>
    </div>
    
    <!-- 项目 3 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-24 bg-red-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">另一个短卡片</h3>
        <p class="text-gray-600 text-sm">简洁的内容展示。</p>
    </div>
    
    <!-- 项目 4 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-64 bg-yellow-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">长内容卡片</h3>
        <p class="text-gray-600 text-sm mb-3">
            这是一个包含大量内容的卡片示例。它展示了 Grid 布局如何处理不同高度的项目。
        </p>
        <p class="text-gray-600 text-sm mb-3">
            每个网格项目都会根据其内容自动调整高度,创造出自然的瀑布流效果。
        </p>
        <p class="text-gray-600 text-sm">
            这种布局非常适合展示不同类型和长度的内容。
        </p>
    </div>
    
    <!-- 项目 5 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-40 bg-purple-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">图片展示</h3>
        <p class="text-gray-600 text-sm">专注于视觉内容的卡片。</p>
    </div>
    
    <!-- 项目 6 -->
    <div class="bg-white rounded-lg shadow-sm border p-4">
        <div class="h-20 bg-pink-100 rounded mb-4"></div>
        <h3 class="font-semibold mb-2">小型卡片</h3>
        <p class="text-gray-600 text-sm">紧凑的信息展示。</p>
    </div>
</div>

5.6 实践案例:响应式仪表板

<!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>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        .dashboard-grid {
            display: grid;
            grid-template-areas: 
                "header header header header"
                "sidebar main main main"
                "sidebar footer footer footer";
            grid-template-rows: auto 1fr auto;
            grid-template-columns: 250px 1fr 1fr 1fr;
            gap: 1rem;
            min-height: 100vh;
        }
        
        @media (max-width: 768px) {
            .dashboard-grid {
                grid-template-areas: 
                    "header"
                    "main"
                    "sidebar"
                    "footer";
                grid-template-rows: auto 1fr auto auto;
                grid-template-columns: 1fr;
            }
        }
        
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 1rem;
        }
        
        .chart-grid {
            display: grid;
            grid-template-columns: 2fr 1fr;
            gap: 1rem;
        }
        
        @media (max-width: 1024px) {
            .chart-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body class="bg-gray-100">
    <div class="dashboard-grid p-4">
        <!-- 头部 -->
        <header class="bg-white rounded-lg shadow-sm p-4" style="grid-area: header;">
            <div class="flex items-center justify-between">
                <div class="flex items-center space-x-4">
                    <div class="w-8 h-8 bg-blue-600 rounded"></div>
                    <h1 class="text-xl font-bold text-gray-900">数据仪表板</h1>
                </div>
                <div class="flex items-center space-x-4">
                    <button class="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition duration-200">
                        导出报告
                    </button>
                    <div class="w-8 h-8 bg-gray-300 rounded-full"></div>
                </div>
            </div>
        </header>
        
        <!-- 侧边栏 -->
        <aside class="bg-white rounded-lg shadow-sm p-4" style="grid-area: sidebar;">
            <nav class="space-y-2">
                <a href="#" class="flex items-center space-x-3 text-blue-600 bg-blue-50 px-3 py-2 rounded-lg">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"></path>
                    </svg>
                    <span>概览</span>
                </a>
                <a href="#" class="flex items-center space-x-3 text-gray-600 hover:text-blue-600 px-3 py-2 rounded-lg hover:bg-gray-50">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
                    </svg>
                    <span>分析</span>
                </a>
                <a href="#" class="flex items-center space-x-3 text-gray-600 hover:text-blue-600 px-3 py-2 rounded-lg hover:bg-gray-50">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z"></path>
                    </svg>
                    <span>用户</span>
                </a>
                <a href="#" class="flex items-center space-x-3 text-gray-600 hover:text-blue-600 px-3 py-2 rounded-lg hover:bg-gray-50">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
                    </svg>
                    <span>设置</span>
                </a>
            </nav>
        </aside>
        
        <!-- 主内容 -->
        <main class="space-y-6" style="grid-area: main;">
            <!-- 统计卡片 -->
            <div class="stats-grid">
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <div class="flex items-center justify-between">
                        <div>
                            <p class="text-sm font-medium text-gray-600">总收入</p>
                            <p class="text-2xl font-bold text-gray-900">¥45,231</p>
                        </div>
                        <div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
                            <svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1"></path>
                            </svg>
                        </div>
                    </div>
                    <div class="mt-4">
                        <span class="text-green-600 text-sm font-medium">+20.1%</span>
                        <span class="text-gray-600 text-sm">较上月</span>
                    </div>
                </div>
                
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <div class="flex items-center justify-between">
                        <div>
                            <p class="text-sm font-medium text-gray-600">新用户</p>
                            <p class="text-2xl font-bold text-gray-900">2,350</p>
                        </div>
                        <div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
                            <svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
                            </svg>
                        </div>
                    </div>
                    <div class="mt-4">
                        <span class="text-green-600 text-sm font-medium">+180.1%</span>
                        <span class="text-gray-600 text-sm">较上月</span>
                    </div>
                </div>
                
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <div class="flex items-center justify-between">
                        <div>
                            <p class="text-sm font-medium text-gray-600">订单数</p>
                            <p class="text-2xl font-bold text-gray-900">12,234</p>
                        </div>
                        <div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center">
                            <svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
                            </svg>
                        </div>
                    </div>
                    <div class="mt-4">
                        <span class="text-red-600 text-sm font-medium">-3.2%</span>
                        <span class="text-gray-600 text-sm">较上月</span>
                    </div>
                </div>
                
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <div class="flex items-center justify-between">
                        <div>
                            <p class="text-sm font-medium text-gray-600">活跃用户</p>
                            <p class="text-2xl font-bold text-gray-900">573</p>
                        </div>
                        <div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center">
                            <svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
                            </svg>
                        </div>
                    </div>
                    <div class="mt-4">
                        <span class="text-green-600 text-sm font-medium">+201</span>
                        <span class="text-gray-600 text-sm">较上月</span>
                    </div>
                </div>
            </div>
            
            <!-- 图表区域 -->
            <div class="chart-grid">
                <!-- 主图表 -->
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <div class="flex items-center justify-between mb-6">
                        <h2 class="text-lg font-semibold text-gray-900">收入趋势</h2>
                        <select class="border border-gray-300 rounded-lg px-3 py-1 text-sm">
                            <option>最近 7 天</option>
                            <option>最近 30 天</option>
                            <option>最近 90 天</option>
                        </select>
                    </div>
                    <div class="h-64 bg-gray-50 rounded-lg flex items-center justify-center">
                        <p class="text-gray-500">图表占位符</p>
                    </div>
                </div>
                
                <!-- 侧边图表 -->
                <div class="bg-white rounded-lg shadow-sm p-6">
                    <h2 class="text-lg font-semibold text-gray-900 mb-6">流量来源</h2>
                    <div class="space-y-4">
                        <div class="flex items-center justify-between">
                            <div class="flex items-center space-x-3">
                                <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
                                <span class="text-sm text-gray-600">直接访问</span>
                            </div>
                            <span class="text-sm font-medium">40%</span>
                        </div>
                        <div class="flex items-center justify-between">
                            <div class="flex items-center space-x-3">
                                <div class="w-3 h-3 bg-green-500 rounded-full"></div>
                                <span class="text-sm text-gray-600">搜索引擎</span>
                            </div>
                            <span class="text-sm font-medium">35%</span>
                        </div>
                        <div class="flex items-center justify-between">
                            <div class="flex items-center space-x-3">
                                <div class="w-3 h-3 bg-yellow-500 rounded-full"></div>
                                <span class="text-sm text-gray-600">社交媒体</span>
                            </div>
                            <span class="text-sm font-medium">15%</span>
                        </div>
                        <div class="flex items-center justify-between">
                            <div class="flex items-center space-x-3">
                                <div class="w-3 h-3 bg-red-500 rounded-full"></div>
                                <span class="text-sm text-gray-600">其他</span>
                            </div>
                            <span class="text-sm font-medium">10%</span>
                        </div>
                    </div>
                </div>
            </div>
        </main>
        
        <!-- 页脚 -->
        <footer class="bg-white rounded-lg shadow-sm p-4" style="grid-area: footer;">
            <div class="flex items-center justify-between text-sm text-gray-600">
                <p>&copy; 2024 数据仪表板. 保留所有权利.</p>
                <p>最后更新: 2024年1月15日 14:30</p>
            </div>
        </footer>
    </div>
</body>
</html>

5.7 Grid 最佳实践

5.7.1 性能优化

  • 避免过度复杂的网格:保持网格结构简单明了
  • 合理使用 auto-fit 和 auto-fill:根据实际需求选择合适的自动填充方式
  • 优化重绘和重排:避免频繁改变网格结构

5.7.2 可访问性考虑

  • 保持逻辑阅读顺序:确保网格项目的视觉顺序与 DOM 顺序一致
  • 提供适当的焦点管理:确保键盘导航的合理性
  • 使用语义化标签:结合适当的 HTML 语义标签

5.7.3 浏览器兼容性

  • 渐进增强:为不支持 Grid 的浏览器提供降级方案
  • 使用 @supports:检测浏览器对 Grid 的支持
  • 测试多种浏览器:确保在主流浏览器中正常工作

5.8 本章总结

在本章中,我们全面学习了 CSS Grid 布局系统:

核心要点

  1. Grid 基础:理解网格容器、项目和相关术语
  2. 容器属性:掌握网格轨道定义、间距和对齐
  3. 项目属性:学会网格线定位和区域命名
  4. 响应式设计:创建自适应的网格布局
  5. 布局模式:掌握常用的 Grid 布局模式

最佳实践

  • 合理选择 Grid 和 Flexbox
  • 使用语义化的网格区域命名
  • 注意性能和可访问性
  • 提供适当的浏览器兼容性支持

下一步

在下一章中,我们将学习响应式设计原理,了解如何创建适配各种设备的布局。

5.9 练习题

  1. 仪表板练习:创建一个包含头部、侧边栏、主内容和页脚的响应式仪表板
  2. 卡片网格练习:使用 auto-fit 创建一个自适应的产品卡片网格
  3. 复杂布局练习:结合 Grid 和 Flexbox 创建一个复杂的页面布局

练习提示

  • 先设计网格结构,再添加内容
  • 考虑不同屏幕尺寸下的布局变化
  • 注意网格项目的对齐和分布
  • 测试内容溢出的处理方式