Ant Design Grid 水平排版指南:详解 Row justify 的六种排列方式
导读
Ant Design 的 Grid(栅格)系统基于 Flex 布局实现,其核心交互之一是控制一行内子元素(Col)在水平方向上的排列方式。本文将围绕 flex 排版示例 展开,系统讲解 Row 组件的 justify 属性所支持的 start、center、end、space-between、space-around、space-evenly 六种取值,并结合源码解释每种取值对应的底层 CSS 行为,帮助你彻底掌握“子元素在其父节点中的水平排版方式”。读完你将能够:熟练使用 justify 完成左对齐、居中、右对齐及各类等距分布布局,理解响应式对象写法,并知晓与垂直对齐 align、排序 order、弹性填充 flex 等配套属性的协作方式。
什么是“布局基础 / Typesetting”
在 flex.md 的说明中,这一示例被定义为“布局基础”(Layout basic):子元素根据不同的值 start、center、end、space-between、space-around 和 space-evenly,分别定义其在父节点里面的排版方式。
这里的“父节点”就是 Row,“子元素”即直接放置在 Row 中的 Col。Ant Design 栅格体系的约束是:内容只能放在 Col 中,而 Row 中只允许直接放置 Col(参见 Grid 组件总览)。当 Row 内的所有 Col 宽度之和不足一行时,多余空间如何分配,就完全由 justify 决定。
示例完整代码
flex.tsx 用同一组 Col span={4}(共 4 列、每列占 24 栅格中的 4 格),分别配上六种 justify 值,直观对比每种排版效果:
import React from 'react';
import { Col, Divider, Row } from 'antd';
import { createStyles } from 'antd-style';
const useStyles = createStyles((props) => {
const { css } = props;
return {
rowContainer: css`
background-color: rgba(128, 128, 128, 0.08);
`,
};
});
const App: React.FC = () => {
const { styles } = useStyles();
return (
<>
<Divider titlePlacement="start">sub-element align left</Divider>
<Row className={styles.rowContainer} justify="start">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
<Divider titlePlacement="start">sub-element align center</Divider>
<Row className={styles.rowContainer} justify="center">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
<Divider titlePlacement="start">sub-element align right</Divider>
<Row className={styles.rowContainer} justify="end">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
<Divider titlePlacement="start">sub-element monospaced arrangement</Divider>
<Row className={styles.rowContainer} justify="space-between">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
<Divider titlePlacement="start">sub-element align full</Divider>
<Row className={styles.rowContainer} justify="space-around">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
<Divider titlePlacement="start">sub-element align evenly</Divider>
<Row className={styles.rowContainer} justify="space-evenly">
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
</>
);
};
export default App;
代码要点:
Divider titlePlacement="start"用作分节标题,标示每一段的排版语义(左对齐 / 居中 / 右对齐 / 两端等距 / 环绕等距 / 完全等距),方便肉眼对比。className={styles.rowContainer}通过antd-style的createStyles给每行加上浅灰背景(rgba(128, 128, 128, 0.08)),突出“容器内子元素的分布范围”。- 每个
Row仅改变justify,Col完全相同,从而保证差异全部由justify引起,是演示水平排版最干净的方式。
六种 justify 取值的语义与底层实现
justify 的可选值在 row.tsx 中被定义为常量数组:
const _RowJustify = [
'start',
'end',
'center',
'space-around',
'space-between',
'space-evenly',
] as const;
Row 渲染时,会根据该值拼接出 ant-row-{justify} 形式的类名(见 row.tsx 中的 clsx 逻辑),随后由 style/index.ts 中的样式表将其映射为 Flex 容器的 justify-content:
justify 取值 |
生成的类名 | 底层 CSS 值 | 排版效果 |
|---|---|---|---|
start |
ant-row-start |
justify-content: flex-start |
子元素靠左(X 轴起点)排列,这是默认值 |
center |
ant-row-center |
justify-content: center |
子元素在父节点内水平居中 |
end |
ant-row-end |
justify-content: flex-end |
子元素靠右(X 轴终点)排列 |
space-between |
ant-row-space-between |
justify-content: space-between |
两端贴边,子元素之间的间距相等(两端无空隙) |
space-around |
ant-row-space-around |
justify-content: space-around |
每个子元素两侧间距相等,首尾元素外侧只有单侧间隙的一半 |
space-evenly |
ant-row-space-evenly |
justify-content: space-evenly |
所有间隙(含首尾外侧)完全相等 |
对应源码节选(style/index.ts):
// The origin of the X-axis
'&-start': { justifyContent: 'flex-start' },
// The center of the X-axis
'&-center': { justifyContent: 'center' },
// The opposite of the X-axis
'&-end': { justifyContent: 'flex-end' },
'&-space-between': { justifyContent: 'space-between' },
'&-space-around': { justifyContent: 'space-around' },
'&-space-evenly': { justifyContent: 'space-evenly' },
与此同时,Row 根节点在 style/index.ts 中被定义为标准的 Flex 容器:
[componentCls]: {
display: 'flex',
flexFlow: 'row wrap',
minWidth: 0,
...
}
其中 flexFlow: 'row wrap' 说明:默认允许自动换行(等价于 Row 的 wrap 属性默认为 true),且子元素沿水平主轴排列——这正是 justify-content 能控制水平分布、而 space-between / space-around 在换行后效果会“分段”的根本原因。wrap={false} 时则会追加 ant-row-no-wrap 类将 flex-wrap 设为 nowrap。
需要留意:demo 中四列 span={4} 合计宽度只有 16/24,不足整行,富余空间才会体现为各类等距分布;若子列宽度合计恰好为 24(或超过 24 换行),justify 的分布效果将不再明显。
更多能力:响应式 justify、垂直对齐与 order
1. justify 支持响应式对象写法
justify 除了接收上述字符串,还支持以断点为键的对象写法:{ xs: ..., sm: ..., md: ..., lg: ..., xl: ..., xxl: ..., xxxl: ... }(对象写法自 4.24.0 起支持,断点与 Bootstrap 4 media query 规则一致)。其解析逻辑见 row.tsx 的 getMergedPropByScreen:若传入字符串则直接使用;若为对象,则按 xs → sm → md → lg → xl → xxl → xxxl 的顺序返回当前屏幕命中的第一个断点值。例如:
<Row justify={{ xs: 'center', md: 'space-between' }}>
<Col span={4}>col-4</Col>
<Col span={4}>col-4</Col>
</Row>
配合屏幕宽度检测 Hook useBreakpoint(row.tsx 内部调用),即可实现“小屏居中、宽屏两端分布”的响应式排版。对应测试见 grid/index.test.tsx:当 matchMedia 命中 (max-width: 575px) 时,<Row justify={{ xs: 'center' }} /> 会渲染出 ant-row-center,而 { lg: 'center' } 不会命中。
2. 属性可响应式更新
justify 与 align 在运行时动态变化也能即时生效。测试 grid/index.test.tsx 验证了将 justify 从 'start' 切换到 'end' 后,DOM 类名会从 ant-row-start 更新为 ant-row-end;同时 row.tsx 依赖类名(而非内联 style)来表达布局,因此在移除 props 或断点不再匹配时相关类会被一并清除,避免脏样式残留(见 grid/index.test.tsx)。
3. 垂直对齐与排序是“另一条轴”
水平排版 justify 与垂直对齐 align、排序 order 相互独立、互不冲突,可组合使用:
- 垂直对齐:见 flex-align 示例,
align取top | middle | bottom | stretch(同样支持响应式对象,stretch为默认行为之一),映射为容器的align-items,类名样式定义在 style/index.ts。 - 排序:见 flex-order 示例,通过
order改变子元素视觉顺序,对应的orderCSS 由 style/index.ts 按 1~24 逐格生成,order-0时则重置为order: 0。 - 弹性填充:若希望
Col不等分、而是按比例或自动撑满剩余空间,可参考 flex-stretch 示例 与 responsive-flex 示例。Col的flex属性在 col.tsx 中被解析:数字按n n auto展开、纯数字字符串与带单位的长度字符串(如'100%')按0 0 flex处理、'auto'映射为1 1 auto。例如给Col传入xs={{ flex: '100%' }}、lg={{ flex: '20%' }}即可在不同断点实现完全自由的 flex 比例(依赖浏览器 CSS Variables 支持)。
常用配套:gutter 与栅格间隔建议
实际布局中水平排版通常与栅格间隔 gutter 配合使用(见 gutter 示例 及 gutter.md)。官方建议间隔取 (16 + 8n)px(n 为自然数),响应式可写成 { xs: 8, sm: 16, md: 24, lg: 32 };需要垂直间距时写成数组 [水平间距, 垂直间距],如 [16, { xs: 8, sm: 16, md: 24, lg: 32 }](垂直间距自 3.24.0 起支持)。gutter 还支持字符串 CSS 单位如 px、rem、vw、vh(自 5.28.0 起)。在实现上,Row 会计算负向 marginInline(见 row.tsx),横向间距则经由 RowContext 提供给各 Col 作为 padding,从而实现“视觉等距、四边对齐”的效果。
小结
Ant Design Grid 的水平排版能力最终都收敛到一行 CSS:Row 把 justify 值翻译成容器的 justify-content。只要掌握 start、center、end、space-between、space-around、space-evenly 的语义差异,理解它作用于“单行内多余空间的分配”,并知道它可以像断点对象那样响应式切换,你就能在使用 <Row><Col /></Row> 构建页面骨架时,精确控制每一行内容的水平节奏。
参考来源
- 示例说明:flex.md、示例代码:flex.tsx
- 组件 API 文档:Grid 组件总览(
justify类型、默认值与版本号) - 属性解析与类名生成:row.tsx
- 布局与排版样式定义:style/index.ts
- 响应式 flex 与
Col属性解析:col.tsx - 相关测试:grid/index.test.tsx
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00