ant-design Drawer 抽屉尺寸详解:size 属性、378px/736px 预设值与自定义宽度实践
导读
本篇基于 ant-design 组件库中 Drawer 抽屉组件的「预设尺寸」(Preset size)示例展开,讲解抽屉默认宽度 378px 与大号抽屉 736px 的来源与使用方式,并延伸到 size 属性从预设枚举到任意数字、CSS 单位字符串的完整取值规则。读完本文,你将掌握如何在左右/上下四种方向上用 size 精确控制抽屉面板尺寸、如何从源码层面理解尺寸解析逻辑,以及 size 与已废弃 width/height 属性的迁移关系。
一、示例背景:一份描述抽屉默认尺寸的演示文档
本仓库 components/drawer/demo/size.md 是 Drawer 组件官方演示站中「Preset size」示例的说明文本,其中文描述如下:
抽屉的默认宽度为
378px,另外还提供一个大号抽屉736px,可以用size属性来设置。
英文版本补充了一个重要信息:默认尺寸实际上按方向分别作用于宽度或高度——
The default width (or height) of Drawer is
378px, and there is a preset large size736px.
也就是说,当抽屉从左右两侧滑出时,378px/736px 是抽屉面板的宽度;当抽屉从顶部或底部滑出时,同样的数值会成为面板的高度。这一设计在 Drawer 组件的 API 文档中同样有印证,见 components/drawer/index.zh-CN.md 中 size 一行的描述「预设抽屉宽度(或高度),default 378px 和 large 736px,或自定义数字」。
二、直接体验:Preset size 演示的完整实现
该演示的可运行代码位于 components/drawer/demo/size.tsx,通过 Radio 单选组切换抽屉尺寸,覆盖了两档预设值和三种自定义写法,能直观看出 size 的完整取值空间:
import React, { useState } from 'react';
import { Button, Drawer, Radio, Space } from 'antd';
import type { DrawerProps } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [size, setSize] = useState<DrawerProps['size']>();
const onClose = () => {
setOpen(false);
};
return (
<>
<Space style={{ marginBottom: 16 }}>
<Radio.Group
value={size}
onChange={(e) => setSize(e.target.value)}
options={[
{ label: 'Large Size (736px)', value: 'large' },
{ label: 'Default Size (378px)', value: 'default' },
{ label: 256, value: 256 },
{ label: '500px', value: '500px' },
{ label: '50%', value: '50%' },
{ label: '20vw', value: '20vw' },
]}
/>
</Space>
<Button type="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
title={`${size} Drawer`}
placement="right"
size={size}
onClose={onClose}
open={open}
extra={
<Space>
<Button onClick={onClose}>Cancel</Button>
<Button type="primary" onClick={onClose}>
OK
</Button>
</Space>
}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
关键点梳理:
- 抽屉面板用
open受控显隐,点击主按钮打开,点击Cancel/OK或右上角关闭按钮(onClose)关闭; size={size}未传值时,useState初值为undefined,此时抽屉回落为默认档378px;title会实时显示当前size值,便于比对各选项的最终效果;- 抽屉示例本身展示了
extra(右上角操作区)与内容区的典型组合,这些内容均不受尺寸切换影响。
运行方式
该 demo 属于组件演示,可通过仓库根目录配置运行 Demo 站点后,在 Drawer(Feedback 分组)下的「Preset size」示例中直接操作验证;也可以在任意 antd 项目内将上述组件代码粘贴到页面中运行,无需额外依赖。
三、size 属性的完整取值规则
结合演示中的 Radio 选项与官方 API 表,size 支持以下取值(类型为 'default' | 'large' | number | string,默认值 'default'):
| 取值示例 | 含义 | 最终生效尺寸 |
|---|---|---|
'default'(或省略) |
预设普通档 | 378px |
'large' |
预设大号档 | 736px |
256 |
数字,直接作为像素值 | 256px |
'500px' |
带 px 单位的字符串 |
500px |
'50%' |
百分比字符串 | 父容器宽度的 50% |
'20vw' |
视口单位字符串 | 视口宽度的 20% |
'500'(纯数字字符串) |
会被解析为数字 | 500px |
从版本演进看,size 预设档自 4.17.0 提供,而允许传入任意字符串(如 '50%'、'20vw')的能力为后续扩展,仓库 API 文档标注为 string 支持在较新版本加入(6.2.0)。若项目需要区分运行环境版本,可在运行时读取 version 判断,当前仓库源码版本见 package.json。
四、源码级解析:378 与 736 从何而来
只看文档容易把 378px/736px 当成魔法数字,实际上它们在 Drawer 实现中一目了然。components/drawer/Drawer.tsx 顶部声明了默认尺寸常量:
const DEFAULT_SIZE = 378;
随后的尺寸解析逻辑(对应 Drawer.tsx)通过 useMemo 将各种合法输入统一收敛为最终像素或单位字符串,再传给底层 @rc-component/drawer:
const drawerSize = React.useMemo<string | number | undefined>(() => {
if (isNumber(size)) {
return size; // 数字类型直接透传(单位 px)
}
if (size === 'large') {
return 736; // 大号预设档
}
if (size === 'default') {
return DEFAULT_SIZE; // 378
}
if (typeof size === 'string') {
if (/^\d+(\.\d+)?$/.test(size)) {
return Number(size); // 纯数字字符串转 number,等价于 px
}
return size; // 其余字符串('500px'、'50%'、'20vw')原样透传给样式
}
if (!placement || placement === 'left' || placement === 'right') {
return width; // 未传 size 时,水平方向回落到 width
}
return height; // 未传 size 时,垂直方向回落到 height
}, [size, placement, width, height]);
可以从中提炼出实现事实:
- 两档预设是硬编码常量:
'large'对应736,'default'(及undefined之外的分支兜底)对应DEFAULT_SIZE = 378; - 纯数字与纯数字字符串统一收敛为像素数:正则
/^\d+(\.\d+)?$/校验通过即Number(size),因此size={500}与size="500"效果一致,均表现为500px; - 带单位的字符串被原样透传:
'500px'、'50%'、'20vw'这类由浏览器解析的 CSS 长度字符串不会经过换算,直接作用于抽屉面板样式; - 与
width/height的回退关系:当size完全未提供时,水平方向(left/right)使用width,垂直方向(top/bottom)使用height,这与 API 文档中「width/height默认值 378」的记载一致。
方向与尺寸的对应关系
placement 决定 size 修饰的是宽还是高,可参考 components/drawer/demo/placement.tsx 中四种方向的使用方式,二者配合关系为:
placement="left" | "right"(默认right)→size控制面板宽度;placement="top" | "bottom"→size控制面板高度。
因此「默认 378px、大号 736px」实际上是对任意方向都成立的口径——上下弹出的抽屉高度默认同样为 378px,large 档为 736px。
五、width/height 已废弃:统一收敛到 size
翻阅 Drawer API 表(components/drawer/index.zh-CN.md)可以发现,width 与 height 两行均带删除线标注「请使用 size 替换」:
|
width| 宽度,请使用size替换 | string | number | 378 | - | × | |height| 高度,在placement为top或bottom时使用,请使用size替换 | string | number | 378 | - | × |
这与第四节的源码回退逻辑互为表里:width/height 并未被立即删除,而是作为未传 size 时的兜底继续生效,同时引导用户迁移到语义更清晰的 size 上。
该迁移策略在实现里也有运行时保障:非生产环境下,Drawer.tsx 会遍历废弃项数组并调用 warning.deprecated 输出控制台提示,其中就包含:
['width', 'size'],
['height', 'size'],
即一旦检测到开发者仍在使用 width/height,antd 会在控制台提示其应改用 size,帮助存量代码平滑升级,而不是直接报错破坏现有页面。
面向旧代码的迁移建议
- 原写法
<Drawer width={512}>与<Drawer height={320} placement="top">在新代码中分别替换为<Drawer size={512}>与<Drawer size={320} placement="top">,语义更统一; - 需要明确保留旧行为又不想触发告警时,可先显式传入
size再升级依赖,避免出现 warning; - 若历史代码依赖 378px 默认宽度,无需任何改动——省略
size即为默认档。
六、测试佐证:378 / 736 / 自定义单位均被验证
仓库对尺寸行为有完整的单测覆盖,见 components/drawer/tests/Drawer.test.tsx,其中四段用例分别验证了:
it('render correctly with size default', () => {
// <Drawer open size="default" ...>
expect(drawerWrapper).toHaveStyle({ width: '378px' });
});
it('render correctly with size large', () => {
// <Drawer open size="large" ...>
expect(drawerWrapper).toHaveStyle({ width: '736px' });
});
it('render correctly with size string', () => {
// <Drawer open size="20vw" ...> → 断言 style.width === '20vw'
// rerender <Drawer open size="500" ...> → 断言 width: '500px'
});
这些用例直接断言抽屉的 .ant-drawer-content-wrapper 节点最终内联样式,恰好构成对文档口径的自动化回归:
size="default"→width: 378px;size="large"→width: 736px;size="20vw"→ 原样保留为20vw(非 px 单位字符串直通);size="500"(纯数字字符串)→ 收敛为width: 500px。
演示页快照 components/drawer/tests/snapshots/demo.test.ts.snap 中也能检索到 Large Size (736px)、Default Size (378px) 等文案与多组 style="width: 378px;" 的渲染结果,进一步印证了「default 档即仓库中大多数渲染快照的默认状态」。
七、实操小结与注意事项
围绕 size.md 这份演示,落地到业务中可总结为以下实践要点:
- 默认尺寸无需配置:Drawer 未指定
size时固定为378px(水平方向为宽、垂直方向为高),这由 Drawer.tsx 的DEFAULT_SIZE常量保证; - 大号抽屉一条属性即可:内容较宽(如表单密集、图片预览)的抽屉推荐
size="large"(736px),无需自行换算宽度; - 按像素值微调用数字:
size={480}与size="480"效果等价,均渲染为480px; - 响应式 / 自适应布局用 CSS 单位字符串:如
size="50%"、size="20vw",浏览器会跟随容器或视口变化实时重算,适合在不同屏幕宽度下保持抽屉占比; - 迁移旧属性:新代码直接使用
size,避免width/height触发废弃告警;旧代码可对照仓库的兜底逻辑确认行为等价后再迁移。
通过「文档演示 → 组件源码 → 单元测试」三层的相互印证,可以确认 size 是 Drawer 面板尺寸的唯一推荐入口,378px 与 736px 两档预设值覆盖了绝大多数场景,而数字与 CSS 单位字符串的透传设计则为精细控制保留了足够弹性。
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 StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00