自适应宽度的卡片列表布局
传统实现
在传统响应式布局的背景下,如果我们需要实现自适应宽度的卡片列表布局,需要媒体查询断点,配合复杂的卡片数量规则,以达成布局效果。
.card-container {
font-size: 0; /* 去掉 inline-block 的空隙 */
}
.card {
display: inline-block;
font-size: 14px; /* 恢复字体大小 */
margin: 16px 0;
width: 100%; /* 默认 1 列 */
background: #fff;
padding: 16px;
}
/* sm: 2 列 */
@media (min-width: 576px) {
.card {
width: 48%;
margin: 1%;
}
}
/* md: 3 列 */
@media (min-width: 992px) {
.card {
width: 30%;
margin: 1.66%;
}
}
/* lg: 4 列 */
@media (min-width: 1200px) {
.card {
width: 22%;
margin: 1%;
}
}
Grid 实现
在 grid 布局日益普及的现在,现在我们可以充分利用 grid 布局的特点,更直观方便地实现自适应卡片布局。
使用 grid-template-columns 可以方便地配置网格布局中列维度的尺寸大小。repeat 属性以更简洁的方式定义重复列属性。
.card-container {
display: grid;
gap: 16px; /* 卡片元素间隔 16px */
grid-template-columns: 1fr; /* 默认 1 列 */
}
.card {
background: #fff;
padding: 16px;
}
/* sm: 2 列 */
@media (min-width: 576px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* md: 3 列 */
@media (min-width: 960px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* lg: 4 列 */
@media (min-width: 1200px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
上面的 grid 方案,我们可以用便利更语义化的方式实现自适应卡片布局,但这种方案仍然强耦合于媒体查询断点。那么有没有更简单的方式来实现,有的兄弟,有的:
.card-container {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}
.card {
background: #fff;
padding: 16px;
}
关注到上面代码的 grid-template-columns 实现,我们可以对其功能做如下解释:
在网格容器中尽可能多地放入宽度至少 320px、最多按可用空间平分(1fr)的列;当容器变窄时列会自动减少列数(换行),当列数大于网格项数量时会保留空列,网格项之间间隔为 16px。
很先进兄弟,很先进。简单的三行代码即可原生实现自适应宽度的卡片列表布局, 且不依赖于媒体查询断点。而且 grid 布局对 2022 年来说兼容性相当好了,很推荐大家使用。
auto-fill vs auto-fit
/* auto-fill:空列保留,项目可能被压缩成更小宽度 */
.grid-fill { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
/* auto-fit:空列折叠,现有项目会扩展填满整行 */
.grid-fit { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }