CSS Grid 5 个冷门技巧,很多人都不知道
Grid 布局大家应该都用过。不过大多数人只会这几行:
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;其实 Grid 还有很多好用的功能,今天整理了5个,每个都能帮你省不少代码。
1. subgrid:让子元素跟着父网格走
场景:做一个卡片列表,每个卡片里有图片、标题、按钮。想让所有卡片的标题行对齐,按钮也在同一水平线上。
以前的做法是给每个卡片设固定高度,或者用 JS 算。现在用 subgrid 就行了:
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.card-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.card-title {
padding: 12px;
font-weight: bold;
}
.card-footer {
padding: 12px;
align-self: end;
}
button {
width: 100%;
padding: 8px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}<div class="cards">
<div class="card">
<img class="card-image" src="image1.jpg" alt="">
<div class="card-title">短标题</div>
<div class="card-footer"><button>查看详情</button></div>
</div>
<div class="card">
<img class="card-image" src="image2.jpg" alt="">
<div class="card-title">这是一个比较长的标题,可能会换行</div>
<div class="card-footer"><button>查看详情</button></div>
</div>
<div class="card">
<img class="card-image" src="image3.jpg" alt="">
<div class="card-title">另一个标题</div>
<div class="card-footer"><button>查看详情</button></div>
</div>
</div>效果就是所有卡片的图片、标题、按钮自动对齐,不管内容多长,底部按钮都在同一行。
兼容性:Chrome 117+、Firefox 71+、Safari 16+。新项目可以直接用,老项目可以等一等。
2. grid-template-areas:一眼看懂布局结构
写响应式布局的时候,你还在用 grid-column: 1 / 3 这种写法吗?试试 grid-template-areas,布局结构一目了然:
.layout {
display: grid;
grid-template-columns: 240px 1fr 200px;
grid-template-rows: 60px 1fr 50px;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
min-height: 100vh;
gap: 1px;
}
.header { grid-area: header; background: #3b82f6; }
.sidebar { grid-area: sidebar; background: #f3f4f6; }
.main { grid-area: main; background: white; }
.aside { grid-area: aside; background: #f3f4f6; }
.footer { grid-area: footer; background: #1f2937; }
@media (max-width: 768px) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"aside"
"footer";
}
}<div class="layout">
<div class="header">头部</div>
<div class="sidebar">侧边栏</div>
<div class="main">主要内容</div>
<div class="aside">右侧栏</div>
<div class="footer">底部</div>
</div>用引号包住区域名,空格分隔列,换行分隔行。改响应式的时候只改 grid-template-areas 就行,不用动子元素的样式。
兼容性:Chrome 57+、Firefox 52+、Safari 10.1+,放心用。
3. minmax + auto-fit:不写媒体查询也能响应式
这是一个很多人不知道的用法,一行代码就能实现响应式网格:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}
.item {
background: #3b82f6;
color: white;
padding: 2rem;
text-align: center;
border-radius: 8px;
}<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>效果是这样的:每列最小200px,最大1fr。容器宽的时候自动排多列,容器窄的时候自动合并,完全不用写媒体查询。
auto-fill 和 auto-fit 的区别:
auto-fill:保留空列,容器里会有空位
auto-fit:折叠空列,最后一行元素会拉伸填满
大多数情况用 auto-fit 效果更好,最后一行不会留空白。
/* 图片画廊的实用写法 */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 8px;
}兼容性:Chrome 57+、Firefox 52+、Safari 10.1+。
4. place-items:最简单的居中写法
你可能习惯用 Flexbox 居中,但 Grid 的居中更简洁:
/* Flexbox 需要3个属性 */
.flex-center {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
border: 1px solid #ccc;
}
/* Grid 只要2个属性 */
.grid-center {
display: grid;
place-items: center;
height: 200px;
border: 1px solid #ccc;
}place-items 是 align-items 和 justify-items 的简写,一个属性就能搞定水平和垂直居中。
全屏居中弹窗的写法:
.overlay {
position: fixed;
inset: 0;
display: grid;
place-items: center;
background: rgba(0, 0, 0, 0.5);
}
.dialog {
background: #fff;
border-radius: 12px;
padding: 32px;
width: min(500px, 90vw);
}<div class="overlay">
<div class="dialog">
全屏居中弹窗<br>
<button>确定</button>
</div>
</div>inset: 0 加上 place-items: center,几行代码就能实现全屏居中弹窗。
兼容性:Chrome 59+、Firefox 45+、Safari 11+。
5. span 语法:精确控制跨列跨行
想让某个元素横跨多列或多行,用 span 比记坐标更方便:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
grid-auto-flow: dense;
}
.item {
background: #3b82f6;
color: white;
padding: 1rem;
border-radius: 8px;
text-align: center;
}
.wide {
grid-column: span 2;
}
.tall {
grid-row: span 2;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}<div class="grid">
<div class="item">1</div>
<div class="item wide">2 (宽)</div>
<div class="item">3</div>
<div class="item tall">4 (高)</div>
<div class="item featured">5 (大)</div>
<div class="item">6</div>
<div class="item">7</div>
</div>实用技巧:grid-column: 2 / -1 表示从第2列开始,跨到最后一列(-1 表示最后一条网格线)。
加上 grid-auto-flow: dense 后,Grid 会自动填补空缺位置,布局更紧凑,不会留下大块空白。
兼容性:Chrome 57+、Firefox 52+、Safari 10.1+。
总结
| 用法 | 解决的问题 | 最低兼容 |
|---|---|---|
| subgrid | 子元素跟父网格对齐 | Chrome 117+ |
| grid-template-areas | 可视化定义布局 | Chrome 57+ |
| auto-fit + minmax | 不用媒体查询的响应式 | Chrome 57+ |
| place-items: center | 最简单的居中方案 | Chrome 59+ |
| span + dense | 灵活跨行跨列、自动填充 | Chrome 57+ |
Grid 的能力远不止 repeat(3, 1fr)。把这5个技巧收藏起来,下次写布局的时候,先想想能不能用 Grid 一步到位。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!