首页
/ ant-design Switch 组件 size 尺寸指南:读懂小号开关演示、尺寸 API 与 Design Token 实现原理

ant-design Switch 组件 size 尺寸指南:读懂小号开关演示、尺寸 API 与 Design Token 实现原理

2026-09-08 20:02:20作者:范垣楠Rhoda

本文以 ant-design 仓库中 Switch 组件的“两种大小(Two sizes)”官方演示(size.mdsize.tsx)为切入点,逐层讲解 size="small" 的用法、size 属性的取值约定、尺寸如何从 Props 传导为 CSS 类,以及小号开关的几何尺寸如何由 Design Token 推导而来。读完本文,你将掌握 Switch 组件尺寸体系的完整使用与定制方法,并能独立用 ConfigProvider.componentSize 实现整页级尺寸统一。

一段演示背后的主题

在 Switch 组件的官方文档页面(components/switch/index.zh-CN.md)中,代码演示区将 ./demo/size.tsx 登记为标题为“两种大小”的示例,其配套说明文档 size.md 全文只有一句话,却是理解该演示的核心:

zh-CNsize="small" 表示小号开关。

en-USsize="small" represents a small sized switch.

这句话揭示的事实是:Switch 组件内置两档外观尺寸——默认的 medium(中号)与 small(小号),而“两种大小”演示的用途正是把这两种规格放在一起,让使用者在同一视图中直观对比它们的视觉差异。

演示源码逐行解读

演示的实际渲染代码位于 size.tsx,完整代码如下:

import React from 'react';
import { Switch } from 'antd';

const App: React.FC = () => (
  <>
    <Switch defaultChecked />
    <br />
    <Switch size="small" defaultChecked />
  </>
);

export default App;

逐行要点:

  • 第一个 <Switch defaultChecked /> 未传 size,走组件默认值 medium,即标准尺寸开关;
  • <br /> 负责让两个开关上下排布(该页面演示区按两列布局渲染,demo.cols = 2);
  • 第二个 <Switch size="small" defaultChecked /> 显式指定 size="small",渲染为小号开关;
  • 两者都设置了 defaultChecked,保证初次进入页面即为“开”状态,便于对比两种尺寸下“开”态的视觉纵深与手柄(handle)位置。

size 属性:取值、默认值与兼容约定

官方 API 文档(index.zh-CN.md API 一节)对 size 的定义如下:

参数 说明 类型 默认值
size 开关大小,可选值:medium small 'medium' | 'small' medium

在实际源码中,尺寸类型的定义更为精细,见 components/switch/index.tsx

export type SwitchSize = Exclude<SizeType, 'large'> | 'default';

这里引用了全局的 SizeType(定义于 components/config-provider/SizeContext.tsx):

export type SizeType = 'small' | 'medium' | 'middle' | 'large' | undefined;

由此可以梳理出两条需要特别注意的兼容约定:

  1. default 已被弃用:历史版本中 Switch 的“标准尺寸”写作 size="default",现已更名为 medium。源码注释明确说明“default is deprecated and will be removed in v7, please use medium instead.”,并且在开发环境下会通过 devUseWarning 输出 size="default" 应改为 size="medium" 的弃用告警(index.tsx)。由于 Switch 不支持 largeSwitchSize 通过 Exclude<SizeType, 'large'> 将其剔除。
  2. size 只取两个有效值medium(默认)与 small。如果传入的是小写字符串,useSize 逻辑会原样采用;因此真正意义上的“小号开关”写法就是演示中的 size="small"

尺寸如何生效:从 Props 到 CSS 类的调用链

size="small" 并不是由 @rc-component/switch 直接消费的,antd 内部做了一层合并与映射。梳理 components/switch/index.tsx 的实现,整条链路是:

  1. useSize(customizeSize) 读取 ConfigProvider 注入的 SizeContext,把“组件显式传入的 size”与“全局上下文 size”合并(实现见 components/config-provider/hooks/useSize.ts):组件没传 size 时沿用全局 context,传了字符串则以组件为准;
  2. 合并结果写入 mergedProps.size
  3. 在拼装 className 时,若 mergedSize === 'small' 则追加 ${prefixCls}-small(即 ant-switch-small)类名:
const classes = clsx(
  contextClassName,
  {
    [`${prefixCls}-small`]: mergedSize === 'small',
    [`${prefixCls}-loading`]: loading,
    [`${prefixCls}-rtl`]: direction === 'rtl',
  },
  ...
);
  1. 带上述类名的开关本体渲染为 @rc-component/switch<RcSwitch>,外层再包裹 <Wave> 以提供点击波纹动效。

也就是说,所有尺寸相关的视觉差异完全由 CSS 层基于 ant-switch-small 类实现,这与快照测试中观测到的结果一致:例如 index.test.tsx 里渲染 size="small" 的开关后,其 DOM 类名即为 ant-switch ant-switch-small ... ant-switch-checked(可对照 snapshots/demo.test.ts.snap 中的小号开关快照)。

小号开关的几何模型:Design Token 驱动的尺寸推导

ant-design 6 代起全面使用 CSS-in-JS + Design Token 生成样式。Switch 组件所有尺寸相关的 Token 都登记在 components/switch/style/index.tsComponentToken 接口中,其中与小号尺寸直接相关的有:

Token 语义
trackHeightSM 小号开关轨道高度
trackMinWidthSM 小号开关最小宽度
handleSizeSM 小号开关手柄(圆形把手)直径
innerMinMarginSM / innerMaxMarginSM 小号开关内部文字/内容区的边距
trackPadding 轨道内边距(大小号共用,固定值 2)

这些 Token 的默认值不是写死的数字,而是从全局基础 Token 推导而来,推导逻辑位于同文件的 prepareComponentToken

const height = fontSize * lineHeight;      // 中号轨道高度
const heightSM = controlHeight / 2;        // 小号轨道高度 = 控件高度的一半
const padding = 2;                         // 固定内边距
const handleSize = height - padding * 2;
const handleSizeSM = heightSM - padding * 2;
trackHeightSM: heightSM,
trackMinWidthSM: handleSizeSM * 2 + padding * 2,
handleSizeSM,
innerMinMarginSM: handleSizeSM / 2,
innerMaxMarginSM: handleSizeSM + padding + padding * 2,

如果采用默认主题(seed token 中 controlHeight: 32,见 components/theme/themes/seed.ts),代入公式可得到一组直观的参考数值:

  • 小号轨道高度 trackHeightSM = 32 / 2 = 16px
  • 小号手柄直径 handleSizeSM = 16 - 4 = 12px
  • 小号最小宽度 trackMinWidthSM = 12 × 2 + 2 × 2 = 28px

可见小号开关在设计上遵循“控件高度减半”的思路,视觉上比中号更紧凑,适合表格行内、设置面板、紧凑工具栏等空间受限场景。需要强调的是,这些数值都会随你通过 ConfigProvider 或 theme.token 修改的全局 Token(如 controlHeightfontSizelineHeight)同步变化,因此请勿把它当作一成不变的像素值。

对应的小号样式规则集中在 genSwitchSmallStylestyle/index.ts),它在 ant-switch-small 作用域内覆盖最小宽度、高度、行高、内容区左右 padding 切换动画、手柄尺寸、加载图标垂直居中偏移以及按下态位移,使小号开关在“开/关切换”“内容平移”“按下反馈”等交互上与中号保持同一套动画模型。

全局统一:用 ConfigProvider 让整页开关变小

在实际产品中,更常见的诉求是“整页/整块区域的开关统一缩小”,而不是逐个写 size="small"。ant-design 为此提供了全局尺寸能力:ConfigProvidercomponentSize 属性支持 SizeType'small' | 'medium' | 'middle' | 'large'),配置后会通过 SizeContextProvider 把尺寸注入子组件树(见 components/config-provider/index.tsx)。

import { ConfigProvider, Switch } from 'antd';

const App: React.FC = () => (
  <ConfigProvider componentSize="small">
    {/* 无需再写 size="small",内部所有支持尺寸的组件都会变小 */}
    <Switch defaultChecked />
    <Switch defaultChecked />
  </ConfigProvider>
);

export default App;

这正是前文 useSize 合并逻辑的意义所在:当 Switch 自身未传 size 时,会从 SizeContext 继承到 small,最终同样命中 ant-switch-small。而显式传 size="small" 的优先级高于全局配置,适合“整体小号、个别中号”的混排需求。

组合使用的注意事项

掌握 size 之后,把它与其它属性组合使用时还需注意几点,均可对照官方文档与源码验证:

  • 文字/图标内容checkedChildren / unCheckedChildren 在小号开关中同样支持,但内容区域基于 innerMinMarginSM/innerMaxMarginSM 计算边距,fontSizeSM 级别的小字号内容观感最佳(样式定义见 style/index.tsant-switch-smallant-switch-inner 的处理)。快照测试中也有 unCheckedChildren="0" 配合 size="small" 的用例可参考;
  • 加载中loading 状态下展示的 LoadingOutlined 图标在小号开关中会按 handleSizeSM 与加载图标尺寸差计算 top 偏移,以保持手柄内居中,不必手动微调;
  • 与 Form 的配合:Switch 的值绑定属性是 checked 而非 value,如需在 Form.Item 下绑定数据,应使用 valuePropName="checked"(FAQ 部分有官方示例),这与尺寸无关但容易在组合使用时踩坑;
  • 语义化样式:从 6.0.0 起,classNames/styles 支持 rootcontentindicator 三个语义结构(见 components/switch/demo/_semantic.tsx),如需对“小号开关单独定制”,可结合函数式 classNames={({ props }) => ...} 判断 props.size === 'small' 来差异化返回类名,相关用法在 semantic.test.tsx 中有完整的断言示例。

小结

回到那则只有一句话的演示文档:size="small" 代表小号开关。在 ant-design 中,这短短一行背后是完整的尺寸体系——medium/small 两档取值与 default 的弃用约定、useSize 合并组件与全局两层尺寸、ant-switch-small 类名的挂载、以及由 controlHeight 等 Token 公式化推导出的 16px 轨道 / 12px 手柄几何模型。理解这条从“演示 → Props → 类名 → Token → CSS”的链路后,无论是要写一个局部小开关,还是要通过 ConfigProvider 统一收紧整个表单的密度,都能在源码层面做到心中有数。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391