- 前端
- UI组件
- 设计系统
【免费下载链接】ant-design
An enterprise-class UI design language and React UI library
本指南聚焦 Ant Design(antd)Space组件的size属性,讲解如何通过预设尺寸(small/middle/large)、自定义数值(数字或[水平, 垂直]数组)以及全局ConfigProvider统一控制元素之间的间距。读完本文,你将掌握size的全部取值形态、默认值解析规则,并能从源码与测试层面理解间距最终是如何落到row-gap/column-gap样式上的。
size是什么:Space 组件的核心间距开关
Space是 Ant Design 提供的用于在水平或垂直方向排布一组元素、并自动为其添加统一间距的布局组件。间距的大小完全由size属性决定。官方 demo 文档 components/space/demo/size.md 对此给出的说明是:
使用
size设置元素之间的间距,预设了small、middle、large三种尺寸,也可以自定义间距,若不设置size,则默认为small。
也就是说,size承担三个职责:
- 三档预设尺寸:直接传字符串
small、middle或large之一; - 自定义数值间距:传任意数字(单位 px),或传
[水平间距, 垂直间距]数组分别控制两个方向; - 默认值兜底:完全不传时,间距回落到
small。
在 API 文档 components/space/index.en-US.md 中,size的类型被定义为Size | Size[],默认值为small,其中Size[](即数组形态)从 4.9.0 版本开始支持。
三种预设尺寸对应的实际像素值
small、middle、large三个字符串并非魔法值,它们在底层被映射为具体的间距像素。映射关系定义在 Space 组件的样式生成文件 components/space/style/index.ts 中:
spaceGapSmallSize: token.paddingXS, // small → paddingXS spaceGapMiddleSize: token.padding, // middle → padding spaceGapLargeSize: token.paddingLG, // large → paddingLG这三个 token 又来自主题的基础尺寸体系。在 components/theme/themes/shared/genSizeMapToken.ts 中,默认主题的尺寸按 4px 步进:
sizeUnit = 4,sizeStep = 4(见 components/theme/themes/seed.ts);sizeXS = 8(4 * (4 - 2))→paddingXS;size = 16(4 * 4)→padding;sizeLG = 24(4 * (4 + 2))→paddingLG。
因此默认主题下三个预设尺寸对应的间距为:
| size 值 | 对应 token | 默认像素值 |
|---|---|---|
small | paddingXS | 8px |
middle | padding | 16px |
large | paddingLG | 24px |
从源码看,间距值并不写死,而是跟随主题 token,因此通过ConfigProvider的theme定制或紧凑(compact)主题,这些预设间距会自动缩放。例如紧凑主题在 components/theme/themes/compact/genCompactSizeMapToken.ts 中对sizeXS、sizeLG等进行了重新计算,Space的预设间距也会随之收紧。
交互式 demo 全解析:从预设到自定义的动态切换
官方 demo 的实现位于 components/space/demo/size.tsx,它用Radio.Group提供了small、middle、large、customize四个选项,并在选择customize时通过Slider动态调整自定义数值:
const [size, setSize] = useState<SizeType | [SizeType, SizeType] | 'customize'>('small'); const [customSize, setCustomSize] = React.useState<number>(0); <Radio.Group value={size} onChange={(e) => setSize(e.target.value)}> {['small', 'middle', 'large', 'customize'].map((item) => ( <Radio key={item} value={item}>{item}</Radio> ))} </Radio.Group> {size === 'customize' && ( <> <Slider value={customSize} onChange={setCustomSize} /> <br /> </> )} <Space size={size !== 'customize' ? size : customSize}> <Button type="primary">Primary</Button> <Button>Default</Button> <Button type="dashed">Dashed</Button> <Button type="link">Link</Button> </Space>这段代码演示了size的两种典型用法:
- 字符串预设:直接把
'small' | 'middle' | 'large'传给size; - 数值自定义:把
Slider拖出的数值(单位 px)直接传给size,间距随滑块实时变化。
demo 中useState的初始值类型来自ConfigProviderProps['componentSize'](即'small' | 'middle' | 'large',见 components/config-provider/SizeContext.tsx),而size属性本身的类型在组件定义中要更宽——可以是SpaceSize(SizeType | number)或[SpaceSize, SpaceSize]数组,定义见 components/space/index.tsx。
数组形态:分别控制水平与垂直间距
除了单一预设字符串和单一数值,size还支持[horizontal, vertical]数组形态,例如:
<Space size={[8, 16]}> <Button>水平间距 8px</Button> <Button>垂直间距 16px</Button> </Space>组件在渲染前会先解构数组(见 components/space/index.tsx):
const [horizontalSize, verticalSize] = Array.isArray(size) ? size : ([size, size] as const);即传入单一值等价于[value, value],两个方向使用相同间距。数组中的每个元素既可以是预设字符串,也可以是数字,两者可混用(如['small', 24])。
默认值:small与全局 ConfigProvider 覆盖
size的默认值解析有两层(见 components/space/index.tsx):
size = space?.size ?? 'small',- 若没有显式传
size,优先使用ConfigProvider中space.size的全局配置(space来自ConfigContext); - 若全局也没有配置,才回落到默认值
'small'。
因此你可以通过ConfigProvider为整个应用统一设置 Space 间距:
import { ConfigProvider, Space } from 'antd'; <ConfigProvider space={{ size: 'large' }}> <Space> <Button>全局生效的 large 间距</Button> <Button>无需逐个配置</Button> </Space> </ConfigProvider>这与 demo 文档中“若不设置size,则默认为small”的描述一致,同时补充了全局覆盖这条真实存在的解析路径。
源码级实现:间距如何变成 CSS
size的取值最终被转换成两类 CSS 实现,其完整逻辑在 components/space/index.tsx 中:
- 预设字符串 → 工具类名:通过
isPresetSize判断是否为small/middle/large之一,若是则给容器追加ant-space-gap-row-{size}与ant-space-gap-col-{size}类名; - 数值 → 内联 gap 样式:通过
isValidGapNumber判断是否为有效数字,若是则直接写入gapStyle.columnGap与gapStyle.rowGap。
对应的工具函数定义在 components/_util/gapSize.ts:
export function isPresetSize(size?: SizeType | string | number): size is SizeType { return ['small', 'middle', 'large'].includes(size as string); } export function isValidGapNumber(size?: SizeType | string | number): size is number { if (!size) { // 此处刻意排除 size = 0 的情况:CSS gap 属性默认值本身就是 0, // 用户传入 0 时可以直接忽略,避免产生无意义的样式 return false; } return typeof size === 'number' && !Number.isNaN(size); }从源码结构可以看出两个值得注意的边界行为:
- 传入
0会被忽略,因为 CSSgap的默认值就是 0,无需额外声明; - 传入
NaN会被安全跳过(isValidGapNumber返回false),不会产生非法样式——测试 components/space/tests/gap.test.tsx 中专门有should NaN work用例,验证<Space size={[NaN, NaN]}>渲染不会抛错。
预设字符串对应的样式类在 components/space/style/index.ts 的genSpaceGapStyle中生成:
&-gap-row-small { row-gap: token.spaceGapSmallSize; } &-gap-row-middle { row-gap: token.spaceGapMiddleSize; } &-gap-row-large { row-gap: token.spaceGapLargeSize; } &-gap-col-small { column-gap: token.spaceGapSmallSize; } &-gap-col-middle { column-gap: token.spaceGapMiddleSize; } &-gap-col-large { column-gap: token.spaceGapLargeSize; }即底层统一使用 CSS Flexbox 的gap属性实现间距(容器本身是inline-flex,见同文件genSpaceStyle),这比传统的margin方案更简洁,也避免了首尾元素多余边距的问题。
测试用例验证
components/space/tests/gap.test.tsx 中有一组针对间距实现的测试,直接印证了上文的行为:
it('should render width empty children', () => { // 不传 size,默认 small:容器应带有 ant-space-gap-row-small 和 ant-space-gap-col-small 类 expect(container.querySelector('div.ant-space')).toHaveClass('ant-space-gap-row-small'); expect(container.querySelector('div.ant-space')).toHaveClass('ant-space-gap-col-small'); }); it('should size work', () => { // 传入数字 10:容器内联样式应为 row-gap: 10px; column-gap: 10px const element = container.querySelector('div.ant-space'); expect(element).toHaveStyle({ rowGap: '10px', columnGap: '10px' }); }); it('should NaN work', () => { // 传入 NaN 数组不应抛错 expect(() => { render(<Space size={[NaN, NaN]}><span>test</span></Space>); }).not.toThrow(); });这三个用例分别验证了:默认值回落为small(类名断言)、数值自定义会写入内联 gap 样式、非法数值NaN的安全兜底。相关 demo 的渲染测试还由 components/space/tests/demo.test.tsx 覆盖,确保官方 demo 页面本身始终可运行。
与其他间距相关属性的配合
size解决的是“元素间距”,而 Space 还有几个与间距配套的属性(见 components/space/index.en-US.md 的 API 表格):
direction:horizontal(默认)或vertical,决定间距作用的方向;垂直布局下row-gap起主要作用;wrap:horizontal方向下是否自动换行,配合row-gap保证换行后行与行之间仍有垂直间距(渲染逻辑见 components/space/index.tsx,wrap开启时设置flexWrap: 'wrap');split:在元素之间插入分隔符(如分割线),与间距叠加使用。
三者与size共同构成了 Space 组件完整的间距控制体系,size是其中最核心、最常用的入口。
小结
Space的size属性提供了从三档预设(small8px /middle16px /large24px,随主题 token 联动)到任意数值、再到[水平, 垂直]数组的完整间距控制能力;未显式设置时按ConfigProvider.space.size→'small'的顺序解析默认值;最终通过预设类名或内联样式落到 CSSgap属性上。无论是快速布局、精细调间距,还是全局统一间距,size都是你控制 Space 布局节奏的第一选择。
- 前端
- UI组件
- 设计系统
【免费下载链接】ant-design
An enterprise-class UI design language and React UI library
相关推荐
Ant Design Flex 组件 gap 间距指南:预设尺寸、自定义数值与主题定制
Ant Design Flex 组件 gap 间距指南:预设尺寸、自定义数值与主题定制 Flex 是 Ant Design 中用于块级元素布局的容器组件,而 g
前端UI组件设计系统Ant Design Space 间距控制详解:用 size 设置组件间的间距
Ant Design Space 间距控制详解:用 size 设置组件间的间距 size 是 Ant Design Space https://link.git
前端UI组件设计系统ant-design Cascader 级联选择器 size 尺寸配置全解:从 size Demo 到源码实现
ant design Cascader 级联选择器 size 尺寸配置全解:从 size Demo 到源码实现 本文以 ant design 仓库中 compo
UI组件前端设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考