CSS Grid和Flexbox是现代CSS布局的两大核心模块。Flexbox适合一维方向上的元素排列,Grid适合二维网格布局。实际项目中两者并非互斥关系,而是根据布局维度选择合适的方案,甚至在同一页面中嵌套使用。本文通过具体案例对比两种布局方案的应用场景和实现方式。
Flexbox弹性布局基础
Flexbox是为解决一维布局问题设计的。它沿主轴(main axis)排列子元素,通过justify-content控制主轴对齐,align-items控制交叉轴对齐。Flexbox的最大优势是处理动态数量子元素和不确定尺寸内容时非常灵活。
核心属性:容器设置display: flex或display: inline-flex,子元素通过flex-grow、flex-shrink、flex-basis控制伸缩比例。flex: 1等价于flex: 1 1 0%,子元素会均分剩余空间。
/* 导航栏布局 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 64px;
}
.navbar .logo {
flex: 0 0 auto;
}
.navbar .menu {
display: flex;
gap: 32px;
flex: 1 1 auto;
justify-content: center;
}
.navbar .actions {
flex: 0 0 auto;
display: flex;
gap: 16px;
}
/* 卡片水平排列,自动换行 */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card-list .card {
flex: 1 1 300px;
min-width: 300px;
max-width: 400px;
}
Grid网格布局核心概念
Grid是二维布局系统,可以同时控制行和列的排列。使用grid-template-columns和grid-template-rows定义网格轨道,gap设置间距。fr单位表示可用空间的比例分配,类似Flexbox中的flex-grow。
repeat()函数简化重复轨道定义,minmax()设置轨道最小最大值,auto-fit和auto-fill实现响应式网格列数自动调整。
/* 经典三栏布局:侧边栏 + 主内容 + 侧边栏 */
.layout {
display: grid;
grid-template-columns: 240px 1fr 300px;
grid-template-rows: 64px 1fr 48px;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* 响应式:窄屏隐藏侧边栏 */
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"footer";
}
.sidebar, .aside { display: none; }
}
/* 自适应网格列数 */
.photo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
响应式布局方案选择策略
选择Grid还是Flexbox取决于布局维度。一维排列(导航栏、按钮组、标签列表)用Flexbox,二维排列(页面框架、图片画廊、表单网格)用Grid。另一个判断标准是子元素数量是否已知:数量固定且需要精确控制位置用Grid,数量动态或内容宽度不确定用Flexbox。
实际项目中常见的组合方式:页面整体框架用Grid,局部区域内部用Flexbox。例如Grid控制header/main/footer的三行布局,main内部用Flexbox排列卡片列表。
/* 页面框架:Grid */
.page {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* 内容区域内部:Flexbox */
.content {
display: flex;
flex-direction: column;
gap: 32px;
}
/* 内容区域中的卡片网格:Grid */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
/* 每个卡片内部:Flexbox */
.product-card {
display: flex;
flex-direction: column;
gap: 12px;
}
.product-card .image {
flex: 0 0 200px;
overflow: hidden;
}
.product-card .info {
flex: 1 1 auto;
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px;
}
.product-card .footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 16px 16px;
}
实战案例:响应式仪表盘布局
管理后台仪表盘是Grid和Flexbox配合使用的典型场景。顶部统计卡片用Grid自适应排列,下方图表区域用Grid控制2:1的宽高比,列表区域用Flexbox处理可变高度内容。
.dashboard {
display: grid;
grid-template-columns: 1fr;
gap: 24px;
padding: 24px;
max-width: 1440px;
margin: 0 auto;
}
/* 顶部统计卡片行 */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}
.stat-card {
display: flex;
flex-direction: column;
gap: 8px;
padding: 20px;
border-radius: 12px;
background: #fff;
}
.stat-card .value {
font-size: 32px;
font-weight: 700;
line-height: 1;
}
.stat-card .label {
font-size: 14px;
color: #666;
}
.stat-card .trend {
display: flex;
align-items: center;
gap: 4px;
font-size: 13px;
}
/* 图表区域:2:1宽高比 */
.charts-row {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
}
@media (max-width: 1024px) {
.charts-row {
grid-template-columns: 1fr;
}
}
@media (max-width: 768px) {
.stats-row {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.stats-row {
grid-template-columns: 1fr;
}
}
Grid和Flexbox的选择不是二选一的问题。理解Flexbox解决一维排列问题、Grid解决二维布局问题这一核心区别,就能在大多数场景中快速做出判断。浏览器兼容性方面,Grid和Flexbox在所有现代浏览器中已完全支持,IE11有部分Grid语法差异需要注意。开发时配合CSS自定义属性(变量)和clamp()函数可以实现更灵活的响应式控制。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/cssgrid-yu-flexbox-bu-ju-shi-zhan-xiang-ying-shi-ye-mian-bu/