
本文详解一种基于 css grid 的巧妙方案,通过拆分视觉上连续的区块为多个独立元素,实现类似 figma 中展示的非矩形、错落有致的 bento 网格布局,适用于现代响应式卡片设计。
本文详解一种基于 css grid 的巧妙方案,通过拆分视觉上连续的区块为多个独立元素,实现类似 figma 中展示的非矩形、错落有致的 bento 网格布局,适用于现代响应式卡片设计。
要复现图中那种“看似一体实则分块”的不规则网格(常被误称为“Bento 布局”),关键在于理解:纯 CSS 无法真正让一个元素跨越非连续行列并保持单一体积感——浏览器渲染引擎要求 grid-column 和 grid-row 的跨度必须是连续的单元格。因此,主流解法是“视觉欺骗”:将一个视觉整体拆分为多个语义独立但样式协同的网格项。
以下是一个经过优化的实现示例,采用三层结构模拟橙色主区块的连贯性:
.d1 {
display: grid;
/* 定义三列两行主体 + 间隙列/行用于视觉分割 */
grid-template-columns: 1fr 0.5em 1fr;
grid-template-rows: 1fr 0.5em 1fr;
gap: 0.5em; /* 替代硬编码边框,提升可维护性 */
margin: 1em;
}
.d1 > * {
min-width: 100px;
min-height: 100px;
border-radius: 1em;
background-color: #ff6b35; /* 使用明确色值替代 orange,便于主题定制 */
}
/* 左上大块:横跨全部三列,仅占第一行 */
.d1 > :nth-child(1) {
grid-column: 1 / -1; /* 更健壮的写法:从第1列到隐式最后一列 */
grid-row: 1;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
/* 左侧竖条:占据第1列,跨第2–3行 */
.d1 > :nth-child(2) {
grid-column: 1;
grid-row: 2 / -1;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
/* 用 inset 阴影模拟顶部虚线分隔,更兼容且可缩放 */
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
/* 中央嵌套块:第2列第2行,内部嵌套白色圆角内容区 */
.d1 > :nth-child(3) {
grid-column: 2;
grid-row: 2;
border-radius: 0;
position: relative;
}
.d1 > :nth-child(3) > div {
position: absolute;
inset: 0;
background: white;
border-radius: 1.3em 0 0 0;
/* 可添加 padding 或 flex 居中内容 */
}
/* 右下独立块:第3列第3行 */
.d1 > :nth-child(4) {
grid-column: 3;
grid-row: 3;
background-color: #4a90e2;
}
<div class="d1"> <div></div> <!-- 视觉主块(上) --> <div></div> <!-- 左侧延伸块 --> <div><div></div></div> <!-- 中央带白底内容区 --> <div></div> <!-- 右下色块 --> </div>
⚠️ 重要注意事项:
- 此方案依赖 DOM 结构与 CSS 的强耦合,不适合动态内容或无障碍优先场景(例如屏幕阅读器会将一个逻辑区域读作四个独立项);
- 若需真正语义化与响应式,建议结合 @container 查询(CSS Container Queries)做断点适配,或使用 JavaScript 辅助计算(如 masonry 布局 polyfill);
- 实际项目中,推荐将该结构封装为自定义元素(Web Component)或 React/Vue 组件,避免重复手写 HTML 结构;
- 替代方案参考:Pinterest Layout(Masonry)、CSS Subgrid(支持度仍有限,暂不推荐生产环境)。
总结:这不是“标准 Grid 的失败”,而是对 CSS 能力边界的合理利用。在设计系统约束下,以可维护性换视觉表现,正是前端工程权衡的艺术。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











