☰
Metro UI CSS Grid 组件完全指南:12 列 Flexbox 响应式网格系统实战详解
2026/10/7 2:25:24 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】Metro-UI-CSS

A progressive front-end framework for creating high-performance responsive reactive web applications!

项目地址:https://gitcode.com/gh_mirrors/me/Metro-UI-CSS
点击查看免费下载

Grid 是 Metro UI CSS 中用于构建复杂响应式布局的纯 CSS 网格组件,它基于 Flexbox 实现了一套 12 列栅格系统,并借助 CSS 容器查询(Container Queries)在组件层面完成断点自适应。阅读本文后,你将掌握.grid/.row/.cell的完整用法、响应式与偏移类名的取用规则、间距控制机制,以及如何通过--grid-gap变量定制属于自己的网格系统。

组件定位与依赖

Grid 组件位于 source/components/grid/,其入口文件 index.js 只有一行:

import "./grid.less";

这说明它是一个纯 CSS 组件:样式全部定义在 grid.less 中,不依赖任何 JavaScript 运行时逻辑,也因此没有插件参数、API 方法和事件。使用时只需引入编译后的 lib/metro.css(或从 source 自行编译),即可直接使用全部网格类名。

快速上手:基础网格布局

网格的基本结构是三层嵌套:.grid容器 →.row行 →.cell-*单元格。以cell-6为例,数字代表该单元格占据 12 列中的 6 列,即一半宽度:

<div class="grid"> <div class="row"> <div class="cell-6">Half width column</div> <div class="cell-6">Half width column</div> </div> <div class="row"> <div class="cell-4">One third</div> <div class="cell-4">One third</div> <div class="cell-4">One third</div> </div> </div>

在 examples/grid.html 与 examples/grid-new.html 两个示例页面中,可以看到完整的实战用法:12 个cell-sm-1拼满一行、cell-md-one-third三等分、cell-md-one-fifth五等分、cell-3 offset-md-6组合等。

列宽计算原理:从源码看 12 列是如何算出来的

grid.less顶部定义了一个关键常量:

@gridCellBaseSize: 8.333335%;

这是 100% ÷ 12 的近似值,即每一"列"的基准宽度。随后通过 Less 的each(range(0, 12))循环批量生成所有列宽类:

each(range(0, 12), .(@k) { .cell-@{k}, .col-@{k} { flex: 0 0 calc(@gridCellBaseSize * @k - var(--grid-gap)); max-width: calc(@gridCellBaseSize * @k - var(--grid-gap)); } .offset-@{k} { margin-left: calc(@gridCellBaseSize * @k); } })

由源码可以推断出三个重要细节:

  1. 宽度 = 列基准 × 列数 − 间距:cell-6的实际宽度为8.333335% × 6 − var(--grid-gap),间距被从单元格宽度中扣除,从而保证列与列之间在 flex 布局中不会因gap而溢出换行。
  2. 偏移只加列宽、不减间距:offset-3的margin-left为8.333335% × 3,恰好推过 3 列的位置。
  3. .row > *默认占满整行:未指定列宽的任意子元素默认flex: 0 0 100%,即一行一个;只有显式添加cell-*类才会进入多列排布。

自动宽度与弹性列

当你不希望使用固定列数时,可以用以下两类单元格:

<div class="grid"> <div class="row"> <div class="cell-auto">Auto width (takes only needed space)</div> <div class="cell">Flexible width (takes remaining space)</div> </div> </div>
  • .cell-auto/.col-auto:flex: 0 0 auto; width: auto; max-width: none,宽度由内容撑开,只占所需空间;
  • .cell/.col:flex-basis: 0; flex-grow: 1,弹性分配行内剩余空间。

源码中.cell-auto, .col-auto, .v-cell-auto, .v-col-auto四个类共用同一组声明(grid.less),v-前缀类与无前缀类等价,可视为同一能力的别名。

响应式网格:基于容器查询的断点机制

这是 Grid 组件最值得关注的实现特性。README 中列举了xs / sm / md / lg / xl / xxl六个断点,而 vars.less 中实际定义的断点更为完整:

断点生效宽度断点生效宽度
fs0lg992px
xs360pxxl1200px
sm576pxxxl1400px
ld640pxxxxl2000px
md768px

与常见的媒体查询(@media)不同,grid.less中的响应式规则使用容器查询(@container)实现:

each(@media-rules, { @container (width >= @value) { .cell-@{key}-half, .col-@{key}-half { ... } each(range(1, 12), .(@k) { .cell-@{key}-@{k}, .col-@{key}-@{k} { flex: 0 0 calc( @gridCellBaseSize * @k - var(--grid-gap) ); max-width: calc( @gridCellBaseSize * @k - var(--grid-gap) ); } .offset-@{key}-@{k} { margin-left: calc( @gridCellBaseSize * @k ); } }) } })

容器查询的"容器"来自.row自身的声明(grid.less):

.row { display: flex; flex-flow: row wrap; gap: var(--grid-gap); container-type: inline-size; container-name: row; min-width: 100%; }

这意味着断点依据的是.row所在容器的内联宽度,而非浏览器视口宽度——组件被嵌入任意宽度的卡片、侧栏或面板时,其响应行为跟随父容器变化,这正是 README"Container query support for component-level responsiveness"(容器查询支持组件级响应)的含义。

响应式用法示例(小屏占满整行、中屏起各占一半):

<div class="grid"> <div class="row"> <!-- Full width on small screens, half width on medium and up --> <div class="cell-12 cell-md-6">Responsive column</div> <!-- Full width on small screens, half width on medium and up --> <div class="cell-12 cell-md-6">Responsive column</div> </div> </div>

每一个断点都拥有与基础类一一对应的响应式版本:.cell-{breakpoint}-{1-12}、.cell-{breakpoint}、.cell-{breakpoint}-auto、.offset-{breakpoint}-{1-12},以及-half、-one-fifth、-two-fifth、-three-fifth、-four-fifth分数类。

列偏移:精确控制起始位置

偏移用于把单元格从行首"推"到指定列位置,offset-{1-12}以列数为单位:

<div class="grid"> <div class="row"> <div class="cell-6 offset-3">Centered column with offset</div> </div> <div class="row"> <div class="cell-4">First column</div> <div class="cell-4 offset-4">Column with offset</div> </div> </div>

第一行中cell-6 offset-3会水平居中显示;第二行中第二个cell-4被offset-4推到第 5 列起始。偏移同样支持响应式版本(如offset-md-6),且偏移量不受--grid-gap影响(源码中margin-left只乘列基准宽度)。

分数宽度:非 12 等分场景

当布局不需要按 12 等分对齐时,可直接使用五等分或对半类:

<div class="grid"> <div class="row"> <div class="cell-one-fifth">20% width</div> <div class="cell-four-fifth">80% width</div> </div> <div class="row"> <div class="cell-two-fifth">40% width</div> <div class="cell-three-fifth">60% width</div> </div> </div>
类名宽度类名宽度
.cell-half/.col-half50%.cell-one-fifth/.col-one-fifth20%
.cell-two-fifth/.col-two-fifth40%.cell-three-fifth/.col-three-fifth60%
.cell-four-fifth/.col-four-fifth80%

由源码可见,分数类在响应式断点下同样可用(-half为flex: 0 0 50%,五等分类为flex: 0 0 calc(20% - var(--grid-gap))等)。

控制列间距:gap 系列与 no-gap

默认情况下.row使用gap: var(--grid-gap),而--grid-gap在:root上默认定义为16px。三种间距控制方式如下:

<div class="grid"> <!-- Default gap (16px) --> <div class="row"> <div class="cell-6">Column</div> <div class="cell-6">Column</div> </div> <!-- Custom gap (8px) --> <div class="row gap-2"> <div class="cell-6">Column</div> <div class="cell-6">Column</div> </div> <!-- No gap --> <div class="row no-gap"> <div class="cell-6">Column</div> <div class="cell-6">Column</div> </div> </div>
  • .row.gap-{0-12}:按 4px 步进设置间距,即gap-1 = 4px、gap-2 = 8px、gap-3 = 12px……源码通过unit(@v * 4, px)生成(grid.less),最终反映为行级--grid-gap覆盖;
  • .row.no-gap:等价于--grid-gap: 0px,完全去除列间距;
  • 行与行之间同样以var(--grid-gap)作为margin-top(.row + .row规则),因此行距与列距保持一致;
  • 单元格默认padding: 0,间距完全由gap承担。

用 CSS 变量定制网格

间距并非写死,而是由变量驱动,便于整体或局部定制:

变量默认值(浅色模式)深色模式说明
--grid-gap16px16px网格列之间的间距

在任意作用域覆盖该变量即可改变网格间距:

/* Custom styling example */ .my-custom-grid { --grid-gap: 24px; }
<div class="grid my-custom-grid"> <div class="row"> <div class="cell-6">Column</div> <div class="cell-6">Column</div> </div> </div>

由于列宽公式(8.333335% × k − var(--grid-gap))和行距(margin-top: var(--grid-gap))都引用该变量,一处修改即可让整组网格的间距与列宽同步适配。

可用 CSS 类速查表

网格容器

类名作用
.grid主网格容器,display: flex; flex-flow: column

行

类名作用
.row行容器,flex 横向换行排布
.row.gap-{0-12}自定义间距(gap-0 = 0px,gap-1 = 4px,gap-2 = 8px,以此类推)
.row.no-gap移除列间距

列

类名作用
.cell-{1-12}/.col-{1-12}固定列宽(1–12 列)
.cell/.col弹性列,占满剩余空间
.cell-auto/.col-auto自动宽度列,只占内容所需空间
.offset-{1-12}列偏移(1–12 列)

分数列

.cell-one-fifth/.col-one-fifth(20%)、.cell-two-fifth/.col-two-fifth(40%)、.cell-three-fifth/.col-three-fifth(60%)、.cell-four-fifth/.col-four-fifth(80%)、.cell-half/.col-half(50%)。

响应式列:对每个断点(fs / xs / sm / ld / md / lg / xl / xxl / xxxl,README 仅列示 xs–xxl,实际断点全集以 vars.less 为准)提供.cell-{breakpoint}-{1-12}、.cell-{breakpoint}、.cell-{breakpoint}-auto、.offset-{breakpoint}-{1-12},以及-half与四个-fifth分数版本。

间距规则:列默认间距 16px;行距等于列距;单元格默认无内边距。

源码、示例与测试验证

  • 样式实现:source/components/grid/grid.less
  • 组件入口(纯样式导入):source/components/grid/index.js
  • 断点变量定义:source/include/vars.less
  • 编译产物(可直接引用):lib/metro.css
  • 实战示例页:examples/grid.html、examples/grid-new.html(后者覆盖了 12 等分、三等分、五等分、偏移、no-gap等组合场景)
  • 自动化测试:tests/grid.test.js 通过 examples/grid.html 页面加载与运行时错误检查验证组件可用性

总而言之,Metro UI CSS 的 Grid 组件以".grid纵向、.row横向、.cell定宽"的三层模型,配合容器查询驱动的断点体系和变量化的间距控制,为响应式布局提供了一套零 JavaScript 依赖、可在任意父容器内自适应的完整方案。需要组件级响应布局时,它是最直接的选择。

  • 前端
  • UI组件

【免费下载链接】Metro-UI-CSS

A progressive front-end framework for creating high-performance responsive reactive web applications!

项目地址:https://gitcode.com/gh_mirrors/me/Metro-UI-CSS
点击查看免费下载
上一篇:免费开源AMD Ryzen调试工具SMUDebugTool:终极硬件控制指南
下一篇:YimMenu Lua 事件系统实战:event 表与 menu_event 事件注册指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询