CSS Flex 布局和 Grid 布局怎么选?

本文探讨了CSS Flexbox和Grid布局的区别,以及如何根据组件显示需求选择合适布局。Flexbox适用于一维布局,如网站导航、操作列表、表单元素等,而Grid布局适合二维布局,如侧边栏+内容区、卡片网格。文章还提供了多种使用场景的示例,并介绍如何结合使用两种布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CSS 中的 Flex 布局和 Grid 布局都是非常强大的布局方案,那什么情况下应该使用 Grid 布局,什么情况下应该使用 Flex 布局呢?本文就来通过一些示例看看两者之间的区别以及使用场景!

Grid 和 Flexbox 的区别

Grid 是一个二维布局模型,它有列和行。而 Flexbox 是一个一维布局模型,可以将其子项目布局为列或行,但不能同时布局。

/* Flexbox */
.wrapper {display: flex;
}

/* Grid */
.wrapper {display: grid;grid-template-columns: 2fr 1fr;grid-gap: 16px;
} 

可以看到,Flexbox 正在布局元素的内联列表(对一行元素进行布局),而 CSS 网格使它们组成列和行的网格。当然,也可以使用 Flexbox 布局对一列元素进行布局:

/* Flexbox */
.wrapper {display: flex;flex-direction: column;
} 

如何决定使用哪个?

在选择其中一种布局时,可以考虑以下问题:

  • 组件的子项如何显示? 内联还是作为列和行?
  • 组件如何在各种尺寸的屏幕上显示?

大多数情况下,如果组件的子项都以内联的方式显示,那么 Flexbox 布局可能是最好的解决方案。考虑以下组件:

这个组件中包含两个子元素,需要在一行中显示,就非常适合使用 Flex 布局。

如果布局需要多个列和行,那么 Grid 布局就是最合适的解决方案。考虑以下组件:

看完这些示例,下面来通过一些具体的示例学习如何决定使用哪个布局方案。

使用场景

CSS Flexbox

(1)网站导航

大多数情况下,网站导航可以使用 CSS Flexbox 来构建。最常见的模式就是左侧为网站 Logo,右侧为网站导航,中间为空白区域。Flex 就可以轻松实现这个布局:

布局代码如下:

.site-header {display: flex;flex-wrap: wrap;justify-content: space-between;
} 
(2)操作列表

操作列表通常由一组可以执行的操作按钮组成,它们排列在一行中:

可以看到,这些操作按钮都是相邻的,并且是水平分布的。这种情况就非常适合使用 Flex 来布局:

.actions-list {display: flex;
}

.actions-list__item {flex: 1;
} 

下面这种包含标题栏或操作栏的场景也同样适用 Flex 布局:

这个组件的页眉和页脚都有内联显示的子元素。对于页眉,布局代码如下:

.modal-header {display: flex;justify-content: space-between;
} 

对于页脚,Cancel 按钮比较特殊,可以使用自动左边距将其推到右侧。

.cancel__action {margin-left: auto;
} 
(3)表单元素

下图第一个组件中,左侧的输入框和右侧的按钮组合是 Flexbox 布局的完美用例:

在第二个组件中,使用 Flex 也可以快速完成布局。这里输入框占据了所有剩余空间,其具有动态宽度。布局代码如下:

.input {flex: 1 1 auto;
} 
(4)评论组件

Flexbox 的另一个常见用例就是评论组件。考虑以下示例:

这里左侧是用户的头像,右侧是评论内容,其占据了父元素的剩余空间。

(5)卡片组件

卡片组件有很多类型,最常见的卡片设计如下:

左侧的卡片组件为上下布局,此时 Flex 容器的方向是列。右侧的卡片组件为左右布局,此时 Flex 容器的方向是行,这是 Flex 布局方向的默认值。

.card {display: flex;flex-direction: column;
}

@media (min-width: 800px) {.card {flex-direction: row;}
} 

另一种卡片,图标的下方带有文本,它可以是一个按钮、链接。这种模式下 Flex 布局同样适用:

第一种模式的布局代码如下:

.card {display: flex;justify-content: center;
} 

第二种模式的布局代码如下:

.card {display: flex;flex-direction: column;align-items: center;
} 
(6)Tab 菜单

当涉及到占据整个屏幕宽度的元素并且具有应该填满所有可用空间的项目时,Flexbox 也是完美的解决方案。

这里,每个项目都应该填充可用空间,并且它们的宽度是相等的。通过将容器元素的 display 属性设置为 flex,即可轻松完成。

.tabs__item {flex-grow: 1;
} 
(7)功能列表

Flexbox 的一个很实用功能就是可以反转元素的方向。默认情况下,Flexbox 的方向是从从左到右的行,我们可以可以这样来反转它:

.item {flex-direction: row-reverse;
} 

在下面的例子中,这个功能就非常实用:

在布局时,可以对偶数行的元素使用上述的方向反转的属性值。

(8)内容居中

假设有一个组件,它的内容需要在水平和垂直方向居中。可以通过 text-align 实现文本的水平居中。

.hero {text-align: center;
} 

可以使用 Flexbox 布局让内容在水平和垂直方向居中:

.hero {display: flex;flex-direction: column;align-items: center; /* 水平居中 */justify-content: center; /* 垂直居中 */
} 

CSS Grid

(1)侧边栏+内容区

当有侧边栏和内容区时,网格布局就是一个完美的解决方案。 考虑以下组件:

可以在 CSS 中这样定义:

<div class="wrapper"><aside>Sidebar</aside><main>Main</main>
</div> 
@media (min-width: 800px) {.wrapper {display: grid;grid-template-columns: 200px 1fr;grid-gap: 16px;}aside {align-self: start;}
} 

如果 <aside> 元素不使用 align-self,它的高度将与 main 元素相同,无论内容长度如何。

(2)卡片网格

网格布局从名字就可以很好地理解,它很适合布局卡片网格:

布局代码如下:

.wrapper {display: grid;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));grid-gap: 16px;
} 

这里的列宽至少为 200px,如果空间不够,它会将卡片换行。如果视口宽度小于 200px,上面的布局会出现水平滚动。

我们可以仅在视口宽度足够时才添加网格布局的定义:

@media (min-width: 800px) {.wrapper {display: grid;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));grid-gap: 16px;}
} 
(3)部分布局

在下面的设计中,可以使用两次网格布局。第一次将整个区域划分为左右两个区域(左侧的侧边栏,右侧的表单),第二次在表单中使用网格布局。

布局代码如下:

@media (min-width: 800px) {.wrapper {display: grid;grid-template-columns: 200px 1fr;}.form-wrapper {display: grid;grid-template-columns: 1fr 1fr;grid-gap: 16px;}.form-message,.form-button {grid-column: 1 / 3;}
} 

Grid 和 Flexbox 结合使用

上面介绍了这两种布局单独使用的场景,当然也可以结合使用这两种布局。考虑下面的例子,对于卡片列表,可以使用 Grid 布局来实现,对于每个卡片组件,就可以使用 Flexbox 布局来实现:

以下是对布局的要求:

  • 每行卡片的高度应该相等;
  • Read more 链接应位于卡片的末尾,高度不固定;
  • Grid 应该使用 minmax() 函数
<div class="wrapper"><article class="card"><img src="sunrise.jpg" alt="" /><div class="card__content"><h2><!-- Title --></h2><p><!-- Desc --></p><p class="card_link"><a href="#">Read more</a></p></div></article>
</div> 
@media (min-width: 500px) {.wrapper {display: grid;grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));grid-gap: 16px;}
}

.card {display: flex; /* [1] */flex-direction: column; /* [2] */
}

.card__content {flex-grow: 1; /* [3] */display: flex; /* [4] */flex-direction: column;
}

.card__link {margin-top: auto; /* [5] */
} 

对于上面的代码:

1.card 元素作为 Flexbox 的容器;
2.布局方向为 column,表示卡片元素垂直分布;
3.让卡片内容扩展并填充剩余空间;
4.卡片内容作为 Flexbox 的容器;
5.使用 margin-top: auto 将链接下推,无论卡片高度如何,这都会使其保持在末端。

可以看到,Grid 和 Flexbox 结合使用并不难,使用它们可以轻松实现日常开发的大多数布局。

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

### CSS Flexbox 布局Grid 布局的区别及使用场景 #### 1. **基本概念** Flexbox 是一种一维布局模式,主要用于解决单向(水平或垂直)的布局需求。它通过灵活调整子项的空间分布、对齐方式等特性,使得页面元素能够在不同屏幕尺寸下保持良好的适应性[^1]。 相比之下,Grid 布局是一种二维布局模式,允许开发者在同一时间管理行列的结构。这种能力使其非常适合用于构建复杂的网格系统,比如网站的整体框架或者图片画廊等场景[^2]。 --- #### 2. **开启方式** 要启用 Flexbox 布局,只需将父容器的 `display` 属性设置为 `flex` 或 `inline-flex` 即可。例如: ```css .container { display: flex; } ``` 对于 Grid 布局,则需要将父容器的 `display` 设置为 `grid` 或 `inline-grid` 来启动该功能。例如: ```css .container { display: grid; } ``` 两者都支持嵌套使用,但在实际应用中需注意性能优化[^3]。 --- #### 3. **主轴与交叉轴的概念** 在 Flexbox 中存在两个核心维度——主轴(main axis)交叉轴(cross axis)。默认情况下,主轴沿水平方向展开而交叉轴则处于竖直状态;不过可以通过修改 `flex-direction` 改变这一行为[^4]。 而在 Grid 系统里并没有严格区分所谓的“主次”,因为其本质上就是基于行列共同作用形成的矩阵型架构。 --- #### 4. **具体属性对比** | 功能/属性 | Flexbox | Grid | |-------------------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| | 定义容器 | 使用 `display: flex;` | 使用 `display: grid;` | | 控制排列方向 | 利用 `flex-direction` (row/column) | 不单独提供此项,由定义行列决定 | | 子项间距设定 | 需借助 margin/padding 或者 gap | 可直接利用 `gap`, 如 `column-gap`,`row-gap` | | 对齐方式 | 主轴(`justify-content`) & 交叉轴 (`align-items`) | 更加细化的支持多种组合形式 | 更多细节可以参见官方文档说明^. --- #### 5. **典型应用场景分析** ##### (1)**Flexbox 的适用范围** 当面对简单的线性排布任务时,如导航栏设计、按钮组摆放或是表单项整齐化处理等问题,Flexbox 显示出了极大的便利性简洁度[^3]。 示例代码如下所示: ```html <div class="nav-bar"> <a href="#">Home</a> <a href="#">About</a> <a href="#">Contact</a> </div> <style> .nav-bar { display:flex; justify-content:space-around; /* 平均分配剩余空间 */ } </style> ``` ##### (2)**Grid 的擅长领域** 如果目标是要搭建整个页面的大纲轮廓或者是呈现多张照片组成的相册效果的话,那么采用 Grid 将会更加合适一些[^4]. 实例演示: ```html <div class="gallery"> <img src="image1.jpg"/> <img src="image2.jpg"/> ... </div> <style> .gallery{ display:grid; grid-template-columns:repeat(3,minmax(100px,1fr));/* 创建三列表格并自适应宽度变化*/ gap:1em;/* 添加间隙 */ } </style> ``` --- #### 总结 综上所述,虽然二者都能完成一定的布局工作,但由于设计理念的不同决定了它们各自最佳的应用场合。简单来说,如果是针对单一维度内的对象安排考虑Flexbox ,而对于涉及多个纵横交错部分的情况推荐运用 Grid 技术[^1].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值