刚接触 CSS 布局时,很多人都会有这个困惑:Grid 和 Flexbox 看起来都能实现布局,到底该用哪个?其实答案很简单——看布局的维度:
Flexbox:一维布局(单行或单列)。它主要专注于「一行」或「一列」内元素的对齐、分布和弹性伸缩,适合处理线性布局,比如导航栏、卡片内部元素排列、按钮组等。
Grid:二维布局(行+列)。它能同时控制行和列的布局,适合处理复杂的网格结构,比如页面整体布局(头部、侧边栏、主体、底部)、商品网格列表、仪表盘等。
记住一个核心原则:一维用 Flexbox,二维用 Grid。而实际开发中,复杂布局往往需要两者协同——用 Grid 搭建整体框架,用 Flexbox 处理框架内的局部线性布局。
需求:实现「头部+侧边栏+主体+底部」的经典页面布局,其中头部包含导航菜单,主体包含卡片列表,卡片内部元素需要垂直居中对齐。
实现思路:
代码实现(结合 Tailwind CSS):
<!-- 页面整体框架:Grid 布局 -->
<div class="grid grid-cols-1 md:grid-cols-4 grid-rows-auto 1fr auto min-h-screen">
<!-- 头部:Flex 布局实现导航水平排列 -->
<header class="md:col-span-4 bg-white border-b p-4 flex justify-between items-center">
<div class="font-bold text-primary text-xl">Layout Demo</div>
<nav class="hidden md:flex gap-6">
<a href="#" class="hover:text-primary">首页</a>
<a href="#" class="hover:text-primary">文章</a>
<a href="#" class="hover:text-primary">关于</a>
</nav>
</header>
<!-- 侧边栏:Flex 布局实现垂直菜单 -->
<aside class="md:col-span-1 bg-gray-50 border-r p-4 hidden md:flex flex-col gap-4">
<a href="#" class="py-2 hover:bg-primary/10 px-3 rounded">菜单1</a>
<a href="#" class="py-2 hover:bg-primary/10 px-3 rounded">菜单2</a>
<a href="#" class="py-2 hover:bg-primary/10 px-3 rounded">菜单3</a>
</aside>
<!-- 主体:Grid 实现卡片网格,内部用 Flex 对齐 -->
<main class="md:col-span-3 p-6 bg-gray-50/50">
<h2 class="text-xl font-bold mb-4">卡片列表</h2>
<div class="bg-white rounded-lg p-4 border flex flex-col items-center text-center">
<div class="w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center mb-3">
<div class="w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center mb-3">
<i class="fa fa-image text-primary text-2xl"></i>
</div>
<h3 class="font-medium mb-2">卡片2</h3>
<p class="text-gray-500 text-sm">Grid + Flexbox 协同布局示例</p>
</div>
<div class="bg-white rounded-lg p-4 border flex flex-col items-center text-center">
<div class="w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center mb-3">
<i class="fa fa-user text-primary text-2xl"></i>
</div>
<h3 class="font-medium mb-2">卡片3</h3>
<p class="text-gray-500 text-sm">Grid + Flexbox 协同布局示例</p>
</div>
代码说明:这个案例中,Grid 负责页面大的区块划分(行和列的整体布局),而 Flexbox 则负责处理每个区块内部的线性排列(头部导航水平排列、侧边栏菜单垂直排列、卡片内部元素居中对齐),两者分工明确,让布局代码更清晰、易维护。
需求:实现电商商品列表布局,每行显示不同数量的商品(移动端1个、平板2个、桌面3个),每个商品卡片包含图片、标题、价格、按钮,按钮需要右对齐,标题超出两行省略。
实现思路:
代码实现:
<!-- 商品列表:Grid 响应式布局 -->
<div class="container mx-auto px-4 p-6">
<h2 class="text-xl font-bold mb-6">热门商品</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- 商品卡片:Flex 垂直布局 -->
<div class="bg-white rounded-lg border overflow-hidden flex flex-col h-full">
<div class="h-48 overflow-hidden">
<img src="https://picsum.photos/id/26/400/400" alt="商品1" class="w-full h-full object-cover hover:scale-105 transition-transform">
</div>
<div class="p-4 flex flex-col flex-grow">
<h3 class="font-medium mb-2 line-clamp-2">
2024新款夏季连衣裙 韩版宽松显瘦碎花长裙 气质温柔风女装
</h3>
<p class="text-primary font-bold mb-3">¥199.00</p>
<div class="flex-grow flex items-end justify-end">
<button class="bg-primary text-white px-3 py-1 rounded text-sm">
加入购物车
</button>
</div>
</div>
</div>
<div class="bg-white rounded-lg border overflow-hidden flex flex-col h-full">
<div class="h-48 overflow-hidden">
<img src="https://picsum.photos/id/27/400/400" alt="商品2" class="w-full h-full object-cover hover:scale-105 transition-transform">
代码说明:这里 Grid 解决了商品列表的二维网格排列和响应式适配问题,而 Flexbox 则解决了商品卡片内部的垂直分布(标题、价格、按钮的上下排列)和按钮右对齐的细节问题。通过 flex-grow 让按钮区域自动占据剩余空间,实现了按钮始终靠下对齐的效果,提升了布局的美观度。
Grid 和 Flexbox 不是竞争关系,而是互补关系。Grid 擅长处理二维布局,解决「整体框架」问题;Flexbox 擅长处理一维布局,解决「内部细节」问题。两者协同使用,才能高效地构建出复杂、灵活、易维护的响应式布局。
我的实战经验:遇到布局需求时,先问自己两个问题:① 这个布局是一维还是二维?② 是整体框架还是局部细节?想清楚这两个问题,就能快速判断该用 Grid 还是 Flexbox,或者两者结合。
最后建议大家多动手实践,比如用 Grid + Flexbox 复刻一些知名网站的布局(比如电商商品列表、后台管理系统仪表盘),在实践中掌握两者的协同技巧,才能真正做到融会贯通!