键盘焦点顺序设计解决的是“没有鼠标时,用户下一步能不能预期”这个问题。合格的流程要回答四件事:焦点从哪里进入、按 Tab 如何移动、动态内容出现后落在哪里、任务结束后回到哪里。登录弹窗、筛选菜单和多字段表单的规则不同,不能用全局 tabindex 数字或“顺着 DOM 就行”一笔带过。

先确定当前焦点,再画 Tab 顺序
焦点路径应以用户任务为单位,而不是以视觉层级为单位。从页面进入登录弹窗的路径可以是触发按钮、邮箱、密码、提交、辅助链接;筛选菜单则要区分打开菜单的按钮、菜单项和关闭后的返回点。每一步都写出当前焦点、可执行键位和下一状态。W3C APG 的键盘接口实践强调,焦点移动必须可预测,不能用大量正 tabindex 强行重排。
在 WCAG 2.2 设计检查清单之外补充一张焦点路线图:实线表示 Tab 路径,虚线表示 Enter 或方向键触发,返回箭头表示 Escape 或关闭动作。这样设计、开发和测试讨论的是同一条路径,不会只看静态截图猜行为。

弹窗要规定进入、约束和返回
打开模态弹窗时,焦点通常应落到标题、第一项可编辑字段或能够说明下一步的控件,具体取决于任务。弹窗打开后,Tab 不应跑到背后的页面;关闭后通常将焦点返回触发按钮;如果触发器已删除,应选择任务中合理的后继控件。如果提交操作自然创建了下一项任务,也可以将焦点移到新任务入口,并在规格中说明。若表单提交产生错误,焦点可以落到错误摘要或第一个错误字段,但必须让用户知道错误与字段的关系。
| 弹窗状态 | 焦点落点 | 键位规则 | 离开条件 |
|---|---|---|---|
| 首次打开 | 标题、第一字段或适当动作;不可撤销任务优先考虑较安全动作 | Tab 与 Shift+Tab 在模态弹窗内正反向循环 | 完成、关闭或 Escape |
| 校验错误 | 错误摘要或第一个错误字段 | 错误描述可被读取 | 修正字段后再次提交 |
| 加载中 | 保留当前控件或明确状态 | 避免重复提交 | 成功、失败或取消 |
| 关闭 | 返回触发按钮;触发器消失或任务转移时选择合理后继目标 | 不把焦点丢到页面顶部 | 继续原任务 |
模态对话框指南适合补充弹窗结构;完成结构后,还要明确焦点的时序和返回关系。图中不要把焦点环只画成装饰色,要把它和键位、状态、读屏名称一并标注。
以包含邮箱、密码、登录与关闭按钮的弹窗为例,打开后让邮箱获得焦点;按 Tab 依次到密码、登录和关闭按钮,再回到邮箱,Shift+Tab 则反向移动。按 Escape 关闭后回到页面上的登录入口。如果邮箱格式错误,保留已输入内容,把焦点送到邮箱并关联错误说明。这里的字段顺序要同时体现在页面结构中,不能靠正数 tabindex 拼出一条与阅读顺序相反的路线。
菜单、组合框和选择器不要混成一个控件
菜单按钮常见的行为是 Enter 或 Space 打开,方向键在菜单项间移动,Escape 关闭并回到按钮。组合框则要处理输入值、候选项、选中值和列表展开状态;上下键可以移动候选项,Enter 接受当前建议,Escape 通常关闭已打开的候选面板;面板关闭后是否清空输入,是必须单独说明的可选行为。搜索建议出现时,焦点是否留在输入框、候选项是否被标记,都需要明确。
W3C APG 对菜单按钮和组合框给出了不同模式,设计稿应按实际组件选择模式。不要为了让 Tab 顺序“看起来连续”而把每个菜单项都塞进主流程;用户按 Tab 进入组件,再使用该组件约定的键位操作,路径会更稳定。
列表排序也可以通过操作菜单完成,而不只依靠拖动。拖拽排序的移动菜单与结果反馈把“移动到哪里”、执行后的焦点和顺序反馈放在同一条课程目录流程中讨论。
表单错误和异步状态要能恢复
静态必填错误、服务端错误和异步校验错误的焦点策略不同。静态错误可以在提交后落到错误摘要;字段级错误应靠近字段展示并提供可读名称;异步校验等待时不能把焦点悄悄移走,失败后要保留用户已输入内容。动态插入帮助文案、验证码或二次确认时,先确定插入位置,再决定焦点是否自动进入。
在 表单异步校验状态中记录 idle、loading、success、error 和 retry 五类状态,并在每个状态旁写出焦点落点。移动端表单还需结合移动表单验收,检查键盘遮挡、滚动和触控目标,避免只做桌面键盘测试。
用键盘走查表验收整条路径
| 场景 | 操作序列 | 通过条件 |
|---|---|---|
| 登录弹窗 | 打开→Tab→填写→提交→修错→关闭 | 无鼠标完成,错误可理解,关闭后回到触发点或明确的后继任务 |
| 筛选菜单 | Tab→Enter→方向键;分别验证 Enter 执行与 Escape 取消 | 执行后进入对应任务;取消后回到菜单按钮 |
| 组合框 | 输入→方向键→Enter→清除 | 输入值、候选值和选中值不混淆 |
| 异步表单 | 提交→等待→失败→重试 | 等待/失败有反馈,已填内容和焦点可恢复 |
把这个登录弹窗放到 Pixso 中,保留相同字段和按钮位置,再复制出“邮箱聚焦”“邮箱错误”和“关闭返回”三张状态画板。用统一的焦点环样式标出当前控件,在画板旁写明 Tab、Shift+Tab 和 Escape 的去向。错误画板既要有红色提示,也要能看清焦点环,避免错误样式覆盖键盘反馈。

可以在 Pixso 中绘制弹窗焦点状态,让开发在同一处查看页面结构和操作约定。实现完成后,仍按上表在真实浏览器中正向、反向走查;静态画板能说明焦点规则,键盘和读屏的运行结果要由实际页面确认。
动态内容出现时,先保住用户的上下文
动态内容最容易让焦点“瞬移”:加载结束后弹出成功提示,筛选结果刷新后列表被替换,表单错误插入一段说明,焦点却仍停在已经消失的元素上。设计阶段应为每个动态状态写出焦点所有者。如果内容只是提示,不需要打断当前输入,可以让焦点留在原控件并提供可读的状态消息;如果内容改变了任务结果,例如筛选后只剩一项,就要让用户知道结果变化,并确保焦点仍位于可见、可操作的位置。
弹窗中的焦点约束也有边界。模态弹窗打开时,背景内容通常不可操作,Tab 应在弹窗内部循环;非模态面板则可能允许用户回到背景,不能套用相同的焦点陷阱。切换页面、切换标签或打开抽屉后,要说明焦点是回到触发器、进入新标题,还是停在当前字段。每种选择都应服务于用户下一步,而不是只满足实现习惯。
把焦点规则写进组件验收条件
组件规格中可以增加四个字段:进入方式、内部移动、退出方式和异常恢复。进入方式写清 Tab、Enter、快捷键或脚本聚焦;内部移动写清 Tab、方向键或上下键;退出方式写清 Escape、完成动作和失焦;异常恢复写清错误提示后焦点落点。字段化之后,设计评审、开发实现和测试用例能直接互相映射。
对组合框和菜单尤其要写当前项与已选项的区别。手动选择模式下,用户可以先浏览候选项,再按 Enter 接受建议;自动选择模式可能在失焦时接受当前建议,两种行为要在组件规范中明确,不能混用。清除操作后,焦点应回到输入框或清除按钮,并用状态文本说明结果。若候选列表异步加载,等待、无结果和加载失败也要各有路径。不要只画一个打开状态,然后把所有键位留给开发猜。

从焦点路径反推组件结构
如果一个组件无法画出稳定的焦点路径,通常说明它的职责混在了一起。例如一个看似“可点击的标签”同时负责展开、选择和删除,键盘用户就无法预期按 Enter 会发生什么。可以先把动作拆成触发器、选项和结果,再为每个元素设置名称、状态和键位。组件结构清楚后,焦点顺序会自然变短,测试也更容易覆盖。
焦点样式应有清楚的外轮廓或其他可辨认变化,并分别检查浅色、深色和错误背景。使用 aria-disabled 等仍允许聚焦的禁用模式时,焦点也要可见;原生 disabled 控件通常不进入 Tab 序列。缩放文字后,焦点环不能被裁切;容器有 overflow 或滚动时,还要确认固定操作栏没有遮住当前控件。把实际允许并存的聚焦、按下和错误状态组合检查,避免只验收一个理想状态。
对于跳过链接、页面标题和区域导航,焦点路径应让用户尽快到达主要内容。跳过链接不是装饰,它要在键盘首次进入页面时可见并能跳到正文。单页应用切换路由后,焦点也需要回到新内容的标题或主要区域,不能留在已卸载的导航按钮上。
失败路径也必须有可达的出口
焦点测试不能只走成功路径。提交失败、网络超时、权限不足、没有搜索结果和动态列表为空时,都要能用键盘退出当前状态。加载遮罩出现后,如果用户按 Escape 可以取消,就要明确取消后的焦点;如果不能取消,应让等待状态可被读到并避免焦点进入不可用区域。错误摘要被关闭后,焦点不能落在已经隐藏的容器上。
对于长列表和虚拟滚动,用户按该组件约定的 Tab 或方向键移动到下一项时,列表要滚动到该项并保持可见;删除一项后,焦点通常回到相邻项或删除触发器,而不是页面顶部。设计稿可以用“删除前、删除后、无结果”三个状态画板承载规则,测试用例再覆盖真实数据量,避免只在三行假数据下判断路径正确。
对不可用动作,先区分隐藏、禁用和只读。隐藏元素不进入焦点路径;禁用控件是否可聚焦取决于原生语义和组件模式,不能只画灰色就结束;只读字段仍可能需要被聚焦以复制内容。若用户需要知道按钮不可用的原因,应把说明放在可读位置,不要让原因只能靠悬停查看。验收时逐一核对按钮名称、当前状态和说明是否一致。
参考资料
- W3C APG:Keyboard Interface Practices,用于键盘焦点和操作原则。
- W3C APG:Dialog (Modal) Pattern,用于弹窗进入、约束和返回。
- W3C APG:Menu Button Pattern,用于菜单按钮行为。
- W3C APG:Combobox Pattern,用于组合框焦点和键位。