Flex 管一维,Grid 管二维。把两套布局方案搭配好,90% 的页面骨架都能稳稳搭出来。
浮动和定位的时代过去了,现在做布局主要是 Flex 和 Grid 两套方案。很多人纠结该学哪个,其实它们不是二选一:Flex 适合“一条线”上的排列(一行或一列),Grid 适合“一张网”上的排列(同时管行和列)。理解这个区别,你就知道什么时候用谁。
给容器设 display: flex 后,它就变成弹性容器,子元素默认沿“主轴”排成一行。主轴方向由 flex-direction 决定,默认是 row(横向);垂直于主轴的是“交叉轴”。
.row {
display: flex;
flex-direction: row; /* 主轴横向,默认 */
/* row | row-reverse | column | column-reverse */
}
记住一个核心:justify-content 管主轴方向的对齐,align-items 管交叉轴方向的对齐。方向一变,两个属性管的轴也跟着变,别死记横向纵向。
.bar {
display: flex;
/* 主轴:起点对齐 / 居中 / 末端 / 两端 / 等距 */
justify-content: space-between;
/* 交叉轴:拉伸 / 顶部 / 居中 / 底部 */
align-items: center;
gap: 16px; /* 间距,替代写一堆 margin */
}
justify-content:flex-start / center / flex-end / space-between / space-around / space-evenly。align-items:stretch(默认)/ flex-start / center / flex-end / baseline。gap:子元素之间的间距,比 margin 干净,不会触发 margin 合并。<nav class="nav">
<a class="nav__logo">Logo</a>
<div class="nav__links">...</div>
</nav>
.nav {
display: flex;
justify-content: space-between; /* logo 在左,链接在右 */
align-items: center; /* 垂直居中 */
gap: 24px;
}
.center {
display: flex;
justify-content: center; /* 主轴居中 */
align-items: center; /* 交叉轴居中 */
min-height: 100vh;
}
默认子元素不换行,多了会被挤压。设 flex-wrap: wrap 后才会换行,配合 gap 形成卡片流。
.card-flow {
display: flex;
flex-wrap: wrap; /* 放不下就换行 */
gap: 24px;
}
.card-flow > .card {
flex: 0 1 280px; /* 不放大 / 可收缩 / 基准宽 280 */
}
flex 是 flex-grow flex-shrink flex-basis 的简写:grow 控制有剩余空间时是否放大,shrink 控制空间不够时是否收缩,basis 是初始尺寸。常用三组:
flex: 1:等分剩余空间,常用于自适应主体区。flex: 0 1 280px:固定基准宽、不放大、可收缩,适合卡片流。flex: 0 0 auto:按内容尺寸,不放大不收缩,适合固定按钮。当布局需要同时规划行和列,Grid 更顺手。给容器设 display: grid,再用 grid-template-columns 定义列轨道。下面是最常用的等分多列:
.grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 三等分 */
gap: 30px;
}
1fr 是“一份剩余空间”,repeat(3, 1fr) 就是三等分。它和 Flex 卡片流的区别在于:Grid 的列是容器说了算,子元素乖乖对齐成网格;Flex 是子元素按内容流式排,换行后每行对齐不一定整齐。
.auto-grid {
display: grid;
/* 每列最小 240px,剩余等分:放得下就多列,放不下自动少列 */
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 24px;
}
这一行几乎能解决所有“卡片墙”需求,且天然响应式,不用写媒体查询。
Grid 真正强大的地方在于可以用名字画布局图,复杂页面骨架一眼看懂。先用 grid-template-areas 画出结构,再把子元素 assign 到对应区域:
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"side main"
"footer footer";
min-height: 100vh;
}
.page__header { grid-area: header; }
.page__side { grid-area: side; }
.page__main { grid-area: main; }
.page__footer { grid-area: footer; }
这种写法可读性极强,改布局时只要调 areas 那几行字符串。响应式时甚至能整块重排:
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"side"
"footer";
}
}
给一个简单的判断标准:只关心一个方向的对齐和分布,用 Flex;要同时规划行列、有明确的网格结构,用 Grid。实际项目里常常嵌套使用——外层 Grid 切大区,区内用 Flex 排细节。
把这两套方案练熟,再复杂的页面也拆得开。下一课我们让布局在不同屏幕下都好用——进入响应式断点。