Ant Design Grid 基础栅格完全指南:用 Row 与 Col 实现从堆叠到水平排列的 24 栅格系统
2026/9/19 21:33:39 网站建设 项目流程

Ant Design Grid 基础栅格完全指南:用 Row 与 Col 实现从堆叠到水平排列的 24 栅格系统

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

导读

本文以 Ant Design 官方「基础栅格(Basic Grid)」演示为起点,系统讲解RowCol这对核心布局组件的使用规则与底层原理:从"从堆叠到水平排列"这一最简单的栅格形态出发,你将掌握 24 等分栅格的划分方式、span占位逻辑、列超宽换行行为,并通过阅读仓库源码理解栅格在 Flex 布局下的真实实现,为后续使用gutteroffset、响应式断点等高级能力打下基础。

从一条演示说起:基础栅格在做什么

官方演示 components/grid/demo/basic.md 的说明非常凝练:

从堆叠到水平排列。使用单一的一组RowCol栅格组件,就可以创建一个基本的栅格系统,所有列(Col)必须放在Row内。

这段话包含了两个关键约定:

  1. 一个基本的栅格系统只需要Row+Col两组组件,不需要任何额外配置;
  2. Col必须放在Row内部,这是栅格组件之间唯一的合法父子关系。

对应的完整示例代码位于 components/grid/demo/basic.tsx:

import React from 'react'; import { Col, Row } from 'antd'; const App: React.FC = () => ( <> <Row> <Col span={24}>col</Col> </Row> <Row> <Col span={12}>col-12</Col> <Col span={12}>col-12</Col> </Row> <Row> <Col span={8}>col-8</Col> <Col span={8}>col-8</Col> <Col span={8}>col-8</Col> </Row> <Row> <Col span={6}>col-6</Col> <Col span={6}>col-6</Col> <Col span={6}>col-6</Col> <Col span={6}>col-6</Col> </Row> </> ); export default App;

这段代码只使用了RowColspan一个属性,却完整展示了 4 种最常见的栅格排布:整行单列(24)、两等分(12+12)、三等分(8+8+8)、四等分(6+6+6+6)。"从堆叠到水平排列"描述的正是在默认块级流式布局下纵向堆叠的 DOM 元素,被Row的 Flex 容器编排为水平排列的列的过程。

为什么是 24:栅格系统的设计理念

span的取值范围来自 Ant Design 的 24 栅格设计。组件文档 components/grid/index.zh-CN.md 的「设计理念」一节说明:

在多数业务情况下,Ant Design 需要在设计区域内解决大量信息收纳的问题,因此在 12 栅格系统的基础上,我们将整个设计建议区域按照 24 等分的原则进行划分。……建议横向排列的盒子数量最多四个,最少一个。

选择 24 等分的优势在于其因子丰富:24 可被 2、3、4、6、8、12 整除,因此无论是要做两列、三列、四列还是六列布局,都能用整数span精确等分,避免出现小数宽度。示例中的 12/8/6 正是 24 分别除以 2/3/4 的结果。

源码视角:span 在底层如何变成宽度

span并不是魔法,它在编译期被转换成固定的 CSS 类名(如ant-col-8),再由样式系统生成对应的百分比宽度。核心逻辑位于 components/grid/style/index.ts 的genLoopGridColumnsStyle

const { prefixCls, componentCls, gridColumns } = token; // gridColumns: 24 —— "Row is divided into 24 parts in Grid"(第 186 行)

样式生成循环从 24 一直遍历到 0,对每个栅格数i生成:

{ display: 'var(--ant-display)', // 支持被 Form 等组件覆盖 display flex: `0 0 ${(i / gridColumns) * 100}%`, maxWidth: `${(i / gridColumns) * 100}%`, }

也就是说,<Col span={8} />最终得到的是flex: 0 0 33.333%+max-width: 33.333%flex: 0 0 X%表示"不放大、不缩小、基础宽度为 X%",这正是栅格列等宽、稳定的根本保证。同时,genGridColStyle为所有列设置了position: relative; max-width: 100%; min-height: 1(防止空列塌陷)。

值得注意的是span={0}的特例:样式循环里对i === 0单独生成display: none,因此官方文档将span的 0 值描述为"相当于display: none",这也在源码中得到了印证。

Row本身则是一个 Flex 容器。在 components/grid/style/index.ts 的genGridRowStyle中:

[componentCls]: { display: 'flex', flexFlow: 'row wrap', minWidth: 0, ... }

flexFlow: 'row wrap'意味着主轴水平、允许换行——这正好解释了文档中的另一条规则:如果一个row中的col总和超过 24,多余的col会作为一个整体另起一行排列。换行能力来自 Flex 的wrap特性,而非任何额外逻辑。

规则细化:谁可以放在 Row 里

组件文档 components/grid/index.zh-CN.md 的「概述」一节总结了基础栅格的完整使用规则:

  • 通过row在水平方向建立一组column(简写 col);
  • 你的内容应当放置于col内,并且,只有col可以作为row的直接元素
  • 栅格系统中的列是指 1 到 24 的值来表示其跨越的范围。例如,三个等宽的列可以使用<Col span={8} />来创建;
  • 如果一个row中的col总和超过 24,那么多余的col会作为一个整体另起一行排列。

"只有Col可以作为Row的直接元素"是一条值得强调的约定:Row的子元素会被套用 Flex 布局并接收来自RowContextgutterwrap信息(见 components/grid/RowContext.ts),只有Col会消费这些上下文,非Col子元素虽然能正常渲染,但无法获得栅格间距等能力。

由基础延伸:Row 与 Col 的属性全景

理解了基础栅格,再看Row/Col的完整 API 就水到渠成。两者类型定义分别位于 components/grid/row.tsx 与 components/grid/col.tsx。

Row 的属性

参数说明类型默认值
align垂直对齐方式top|middle|bottom|stretch,或按断点的响应式对象top
gutter栅格间隔:像素值、响应式对象{ xs: 8, sm: 16, md: 24 },或数组[水平间距, 垂直间距]number | object | array0
justify水平排列方式start|end|center|space-around|space-between|space-evenly,或响应式对象start
wrap是否自动换行booleantrue

源码中的取值常量给出了精确范围(components/grid/row.tsx):

const RowAligns = ['top', 'middle', 'bottom', 'stretch'] as const; const RowJustify = [ 'start', 'end', 'center', 'space-around', 'space-between', 'space-evenly', ] as const;

Col 的属性

参数说明类型默认值
span栅格占位格数,为 0 时相当于display: nonenumber-
offset栅格左侧的间隔格数,间隔内不可以有栅格number0
order栅格顺序number0
push栅格向右移动格数number0
pull栅格向左移动格数number0
flexflex 布局属性string | number-
xs / sm / md / lg / xl / xxl响应式栅格,可为栅格数或包含 span/offset/order 等的对象number | object-

Col的类型定义(components/grid/col.tsx)还揭示了ColSize的完整形态:

export interface ColSize { flex?: FlexType; span?: ColSpanType; order?: ColSpanType; offset?: ColSpanType; push?: ColSpanType; pull?: ColSpanType; }

即响应式断点属性除了接收数字(等价于span),还可以接收一个包含spanoffsetpushpullorderflex的对象。

gutter的间距实现值得一提:Row把水平间距的一半以负 margin 施加在自身(marginLeft = gutter[0] / -2),Col通过RowContext拿到gutter后,把一半以 padding 施加在列上(paddingLeft/Right = gutter[0] / 2),从而在不破坏列宽百分比的前提下实现等宽间隔。相关实现见 components/grid/row.tsx 与 components/grid/col.tsx,官方演示 components/grid/demo/gutter.tsx 展示了数字、响应式对象、数组三种写法:

<Row gutter={16}> {/* 固定水平间距 */} <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }} /> {/* 响应式间距 */} <Row gutter={[16, 24]}> {/* [水平间距, 垂直间距] */}

断点与响应式:基础栅格的进阶方向

基础栅格只有span,而实际项目中更常用的是响应式栅格。断点规则同样记录在 components/grid/index.zh-CN.md,并扩展自 Bootstrap 4 的规则:

断点屏幕范围
xs屏幕 < 576px
sm屏幕 ≥ 576px
md屏幕 ≥ 768px
lg屏幕 ≥ 992px
xl屏幕 ≥ 1200px
xxl屏幕 ≥ 1600px

这些断点对应的媒体查询在 components/_util/responsiveObserver.ts 中基于主题 Token 生成:

const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ xs: `(max-width: ${token.screenXSMax}px)`, sm: `(min-width: ${token.screenSM}px)`, md: `(min-width: ${token.screenMD}px)`, lg: `(min-width: ${token.screenLG}px)`, xl: `(min-width: ${token.screenXL}px)`, xxl: `(min-width: ${token.screenXXL}px)`, });

Row会通过useResponsiveObserver订阅窗口媒体查询变化(components/grid/row.tsx 中subscribe/unsubscribe成对出现),因此gutteralignjustify传入对象形式时能随屏幕实时切换。断点值可通过主题 Tokenscreen[XS|SM|MD|LG|XL|XXL]定制。

测试如何验证这些行为

仓库测试 components/grid/tests/index.test.tsx 用大量用例固化了上文所述的实现事实,可作为深入理解栅格行为的对照:

  • 对象与数组形式的gutter都会在Row上产生负 margin(如gutter={[16, 20]}marginLeft/marginRight-8px);
  • 大屏 mock 下gutter={[{ xs: 8, ... xl: 40 }, ...]}得到-20px的边距,验证了响应式间距的"按断点取最近命中值"逻辑;
  • align/justify的响应式对象只在命中断点(如xs)时生成ant-row-middleant-row-center类,未命中断点(如lg)时不生成;
  • justify="space-evenly"会真实产生justify-content: space-evenly的计算样式;
  • Row卸载时会调用useResponsiveObserverunsubscribe,避免内存泄漏。

小结与继续探索

至此,你已经完整掌握了 Ant Design 基础栅格的核心:

  • 组件骨架Row负责水平编排,Col负责占位,所有Col必须放在Row内;
  • 宽度机制span通过 24 等分换算为flex: 0 0 (span/24*100)%的百分比宽度,总和超过 24 时自动换行;
  • 实现原理:整套系统构建在 Flex 布局之上,Rowdisplay: flex; flex-flow: row wrap的容器;
  • 进阶路径gutteroffsetpush/pullorderxs~xxl断点构成了从基础栅格通向响应式布局的完整能力集。

如果想继续深入,建议按以下路径阅读仓库:

  • 更多演示(间距、偏移、排序、对齐、响应式、Flex 填充):components/grid/demo 目录下的gutter.tsxoffset.tsxsort.tsxresponsive.tsx等;
  • 完整 API 文档:components/grid/index.zh-CN.md;
  • 组件入口与导出:components/grid/index.tsx(同时导出了useBreakpointHook);
  • 样式生成细节:components/grid/style/index.ts;
  • 响应式订阅机制:components/_util/responsiveObserver.ts。

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design

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

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

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

立即咨询