现代CSS布局:Grid与Flexbox实战指南

CSS 布局经历了表格布局、浮动布局,终于迎来了 Flexbox 和 Grid 两大神器。它们让网页布局变得简单、灵活。本文将深入讲解两者的核心概念、区别,并通过实战案例帮助你掌握它们。

🎯 目标: 学完本文,你将能够根据不同的布局需求,合理选择 Flexbox 或 Grid,并编写出优雅的响应式界面。

一、Flexbox:一维布局大师

Flexbox(弹性盒模型)适用于一维布局,即要么是水平方向(行),要么是垂直方向(列)。它的核心思想是让容器能够改变子元素的宽高以最佳方式填充可用空间。

基本概念

常用属性

/* 容器属性 */
.container {
    display: flex;           /* 或 inline-flex */
    flex-direction: row;     /* row | column | row-reverse | column-reverse */
    flex-wrap: wrap;         /* nowrap | wrap | wrap-reverse */
    justify-content: center; /* 主轴对齐:flex-start | flex-end | center | space-between | space-around | space-evenly */
    align-items: center;     /* 交叉轴对齐:stretch | flex-start | flex-end | center | baseline */
    align-content: space-between; /* 多行时的交叉轴对齐 */
    gap: 10px;               /* 项目间隙(推荐替代 margin) */
}

/* 项目属性 */
.item {
    flex-grow: 1;            /* 放大比例,默认0 */
    flex-shrink: 1;          /* 缩小比例,默认1 */
    flex-basis: auto;        /* 项目初始大小 */
    flex: 1 1 auto;          /* 以上三个的简写 */
    align-self: center;      /* 覆盖容器的 align-items */
}

示例:水平导航栏

<nav style="display: flex; gap: 20px; background: #2c3e50; padding: 1rem;">
    <a href="#" style="color: white;">首页</a>
    <a href="#" style="color: white;">关于</a>
    <a href="#" style="color: white;">服务</a>
    <a href="#" style="color: white;">联系</a>
</nav>

效果预览(导航链接均匀分布):

首页关于服务联系

二、CSS Grid:二维布局神器

Grid(网格)专为二维布局设计,同时处理行和列。你可以将容器划分为行和列的网格,然后将项目放置到指定的单元格中。

基本概念

常用属性

/* 容器属性 */
.container {
    display: grid;
    grid-template-columns: 200px 1fr 2fr;  /* 定义三列,宽度分别为200px、1份、2份 */
    grid-template-rows: 100px auto 100px;   /* 定义三行 */
    gap: 10px;                              /* 行和列间隙 */
    justify-items: stretch;                 /* 单元格内水平对齐 */
    align-items: stretch;                   /* 单元格内垂直对齐 */
    grid-template-areas: 
        "header header header"
        "sidebar main main"
        "footer footer footer";
}

/* 项目属性 */
.item {
    grid-column: 1 / 3;        /* 从第1条列网格线到第3条(合并两列) */
    grid-row: 1 / 2;           /* 从第1条行网格线到第2条 */
    grid-area: header;         /* 使用命名区域 */
    justify-self: center;      /* 单个项目水平对齐 */
    align-self: center;        /* 单个项目垂直对齐 */
}

示例:经典三行布局

<div style="display: grid; grid-template-rows: 80px 1fr 60px; gap: 5px; height: 300px;">
    <div style="background: #3498db;">Header</div>
    <div style="display: grid; grid-template-columns: 1fr 3fr; gap: 5px;">
        <div style="background: #2ecc71;">Sidebar</div>
        <div style="background: #e74c3c;">Main</div>
    </div>
    <div style="background: #f39c12;">Footer</div>
</div>

效果简化示意:

Header
Sidebar
Main
Footer

三、Flexbox vs Grid:如何选择?

四、实战:构建响应式卡片网格

假设我们要实现一个自适应的卡片列表,在大屏幕显示三列,中等屏幕两列,小屏幕一列。同时每个卡片内部图片和文字用 Flexbox 排列。

HTML 结构

<div class="card-grid">
    <div class="card">
        <img src="https://via.placeholder.com/300x200" alt="demo">
        <div class="card-content">
            <h3>卡片标题</h3>
            <p>卡片描述内容,这里是若干文字。</p>
            <button>查看详情</button>
        </div>
    </div>
    <!-- 更多卡片... -->
</div>

CSS 实现

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 20px;
}

.card {
    display: flex;
    flex-direction: column;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
}

.card img {
    width: 100%;
    height: auto;
}

.card-content {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.card-content button {
    align-self: flex-start;
    margin-top: auto;  /* 将按钮推到底部 */
}

grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); 是实现响应式的关键:自动填充列,每列最小 280px,最大 1fr(等分剩余空间)。当容器宽度不足以容纳多个 280px 时,自动折行。

最终效果示意图(使用简化的纯色代替图片):

Card 1
Card 2
Card 3
Card 4

五、浏览器兼容性与总结

现代浏览器对 Flexbox 和 Grid 的支持已经非常好(包括 IE 的部分支持)。对于生产环境,可以查阅 caniuse.com 确认。

总之,Flexbox 和 Grid 是现代 CSS 布局的基石。掌握它们,你就能轻松应对绝大部分布局需求。多动手练习,很快就能得心应手。

作者:星河hm