模态需要焦点捕获与关闭后归还
别名: 焦点陷阱 · 焦点归还 · 模态焦点 · focus trap
概念解释
模态一旦打开,键盘与辅助技术的焦点必须被关在对话框里,不能 Tab 到后面那层已经锁住的主界面;关掉之后,焦点必须回到打开它的那个控件。这叫焦点捕获与归还(focus trap and restore)。它处理的是「谁在接收输入」,不是「该不该用模态」,也不是「用哪个键关闭」。缺捕获,锁住的表面仍能被读到、被改到;缺归还,关闭后的人掉进文档顶端或一个不相干的控件里。
机制
焦点是输入的唯一入口。主表面在模态下视觉上锁了,若焦点顺序仍包含那些节点,键盘用户会在看不见也点不着的控件上打字、激活,屏幕阅读器会把两层文档读成一篇。捕获把焦点循环限制在对话框的可交互节点上,打开时落到对话框内第一个合理控件(不要无故落到关闭按钮而跳过问题本身)。关闭时若不归还,焦点按文档顺序落到页面起点,空间记忆(「我刚才在第三张卡上」)被拆掉,还可能意外激活顶栏。归还的对象应是触发者;触发者若已卸掉,落到逻辑上的替代位置(被删项的邻行),而不是 body。捕获不是把焦点钉死在一个控件上:对话框内部仍要能 Tab 循环。
怎么研究
用键盘和屏幕阅读器走一遍:打开前的焦点位置、打开后 Tab 是否离开对话框、关闭后焦点落点。自变量:打开方式(按钮 / 自动弹出)、对话框内控件数量、触发者在关闭后是否还在。因变量:焦点逃逸次数、关闭后落点是否为触发者、朗读是否扫到下层。自动弹出且无触发者时,归还策略应事先指定,否则测试会暴露落点随机。
边界
触屏用户不走 Tab,捕获对他们几乎不可见,但开关读屏时立刻可见。非模态面板不应捕获,否则并行操作被焦点策略破坏。嵌套若发生(本不应发生),内层必须捕获到内层,外层在内层存在期间不能接焦点,关闭内层后焦点回到外层而不是主表面。移动平台的系统对话框自带捕获,自绘模态却常漏,不能拿系统行为当已实现。
怎么落地
- 打开时把焦点移进对话框并在其可交互节点内循环;下层节点从顺序里拿掉或标为不可达。
- 关闭时把焦点还给触发控件;触发控件已不在就还给预先约定的替代节点。
- 打开时不要默认聚焦破坏性按钮。
- 验证:只开键盘,打开、在对话框内走一整圈 Tab、关掉。焦点不得出现在下层,关掉后必须回到原按钮。