EN
展现形式 · 概念

Drawer:侧滑抽屉

说明 Drawer 侧滑抽屉与 Modal 的边界,何时用它承载购物车、筛选、移动导航或快速查看,以及模态与非模态抽屉的焦点、Escape、背景 inert、小屏全屏和无 JavaScript 退化要求。

Drawer 是从屏幕边缘滑入的面板,承载购物车、筛选、移动导航或商品快速查看这类需要多次操作、又要保留页面上下文的侧向任务。它描述的是位置与运动方式,不是模态性:阻断背景的抽屉按 Modal 的规则处理,不阻断背景的是非模态侧栏,两者的焦点与键盘要求不同。

适合与不适合

适合加购后查看并修改购物车、在列表页边看结果边调筛选、小屏导航层级、不离开列表的快速查看。不适合必须完整阅读的长内容、结账这类多步骤流程、复杂表单,以及可直接放在页面里完成的低风险操作,这些应改用独立页面或 Inline Form。不要用抽屉自动弹出营销内容。

与相邻模式的区别

相邻模式判据说明
Modal居中打断还是贴边承载Modal 适合短确认;Drawer 承载更长的侧向任务。抽屉以模态方式打开时,焦点与 inert 规则同 Modal
Popover任务量Popover 就近放一段说明或一两个选项;需要多次操作和提交时升级为 Drawer
Overlay叠放对象Overlay 把文字叠在媒体上;Drawer 是叠在整个页面上的面板
独立页面(如 /cart)是否需要独立 URL需要分享、刷新保持状态或结账前完整核对时用页面;抽屉应以页面作为退化方案

优点与缺点

优点缺点
保留背景上下文,减少跳转模态抽屉的焦点、滚动锁定与 inert 实现复杂
贴边布局适合较高的列表小屏几乎占满视口,实际等同全屏页面
加购后可立即核对并继续浏览无独立 URL,刷新后状态丢失

内容与交互要求

标题说明任务(“购物车”“筛选”),提供可见的关闭控件;点击遮罩与 Escape 是补充,不是唯一关闭方式。最终动作(去结账、应用筛选)要有明确按钮和结果反馈。同类抽屉的滑入方向在站内保持一致,用起始侧 / 结束侧而不是写死左右,以适配从右向左的语言;具体选哪一侧属于设计约定,没有标准依据。

先判定模态性:模态抽屉打开后背景不可操作并有遮罩,适合购物车、小屏导航与小屏筛选;非模态侧栏背景仍可操作与滚动、无遮罩,适合桌面端与主内容并列工作的筛选,更接近页面布局的一部分。

响应式与无障碍

模态抽屉遵循 APG 的 Dialog (Modal) 模式:role="dialog" 加 aria-modal="true" 并有名称(aria-labelledby 或 aria-label);打开时焦点移入,Tab 与 Shift+Tab 在其中循环,Escape 关闭,关闭后焦点回到触发元素(触发元素已不存在时落到合理位置)。APG 同时说明,只有代码阻止了外部交互且视觉上遮蔽了背景时才应标记为模态。

背景必须真正 inert。MDN 说明:用 showModal() 打开原生 <dialog> 时浏览器让外部内容 inert,自建实现则需对其余内容应用 inert 属性;inert 使元素不可聚焦、不可点击并从可访问性树中排除,页面需自行提供视觉提示。MDN 还提醒不要给 <dialog> 加 tabindex,并建议用 autofocus 指定初始焦点。内容较长时,APG 示例把初始焦点放在带 tabindex="-1" 的静态段落上,而不是整个对话框。

非模态侧栏不套用上述规则:不标 aria-modal,没有焦点圈定与 Escape 关闭的义务,用普通区域与标题组织,Tab 顺序在触发控件后自然进入。这是依据 Dialog 与 WCAG 原则的推论,APG 没有专门模式。

小屏抽屉宽度接近全屏,不留难以点击的窄遮罩条;WCAG 2.2 的 1.4.10 Reflow 要求内容在 320 CSS 像素宽度下不需二维滚动,抽屉内的列表、价格与按钮放大后仍应可用。动画用 prefers-reduced-motion 降级。

内容变化时的焦点:加购后自动打开抽屉,焦点移入抽屉;删除条目导致列表刷新时,焦点不能随被销毁的节点丢失,应移到相邻条目或抽屉标题,并用 role="status" 说明“已删除”“小计已更新”(见 Toast)。

状态与退化

  • 零项:购物车为空时保留抽屉,展示说明与继续浏览入口,不自动关闭。
  • 一项与多项:结构不变;长列表在抽屉内部滚动,操作按钮固定在底部,避开软键盘与安全区(见 Sticky Bar)。
  • 加载与错误:请求期间禁用重复提交;失败信息留在相关条目旁,不使用会消失的提示。
  • 无 JavaScript:入口是指向独立页面(/cart、筛选页)的真实链接,脚本再增强为抽屉。
  • 减少动态:取消滑动动画。

常承载的内容与模块

购物车条目与摘要(Horizon 购物车解读了页面与抽屉共用组件)、促销与优惠的兑换入口、商品分类与筛选(见 Horizon 集合与搜索)、小屏导航。内容由各自类型或模块维护;总览见功能模块。

平台落点(核验于 2026-09-29):Shopify Help Center 主题设置页写有 Cart type 设置项,可选 Drawer、Page 或 Popup notification,该页对各主题是否一致未逐主题核验。Ajax Cart API 参考页写明 add、change、clear、update 请求可用 sections 参数在响应中携带分区 HTML(最多五个),库存不足时返回 422 及说明文字;分区渲染不在 /cart/add.js 的默认响应中。

发布前检查

  • 这个任务真的需要抽屉,而不是页面或内联区域吗?
  • 抽屉是模态还是非模态?对应的焦点、Escape 与 inert 规则是否成立?
  • 键盘能否打开、操作、关闭并回到触发位置?内容刷新后焦点是否合理?
  • 320 CSS 像素宽度、软键盘与文本放大下能否完成任务?
  • 无 JavaScript 时入口是否指向可用页面?

固定版本主题实现

固定基线为 Dawn v15.3.0 与 Horizon 4.2.0;结论限于这两个提交,均为静态源码分析,未运行验证。

待继续完善

  • 在真实读屏软件与移动浏览器中验证模态与非模态抽屉的焦点和朗读。
  • 抽屉的固定版本实现已有对应解读(见「固定版本主题实现」),未运行浏览器或读屏验证。