E2.22.3dialog focus handoff设计研究

弹层打开后应主动移交焦点,关闭后应归还

别名: 模态焦点捕获 · focus trap · 关闭后焦点回去

概念解释

对话框、抽屉、菜单打开时,键盘和读屏器仍停在底下那一页,等于对着一块看不见的层打字。打开时应把焦点交进弹层;关掉后应还给打开它的那个控件。这叫弹层焦点交接(dialog focus handoff)。它管的是一层界面的进入与退出,不是整页加载时该不该自动聚焦,也不是异步脚本在输入中途抢焦点。

机制

模态在视觉上切断了底下的页,焦点若不跟着走,键盘用户继续 Tab 会在底层不可见控件上转,读屏器仍读底层。交进去通常落在弹层标题或第一个可操作控件,并在层内循环(焦点陷阱),避免逃回底下。关掉时若焦点掉到文档开头或 body,人丢失「我刚才在哪」,得重新找触发按钮。归还到触发者,是把一次往返做成可逆的位置记忆。非模态面板不该陷阱,但仍应在打开时把焦点送进面板,关闭时归还,否则打开等于没打开。

怎么研究

用键盘打开对话框,看焦点是否进入层内、Tab 是否被关在层里、Esc 关闭后焦点是否回到触发按钮。自变量:初始焦点落在标题还是第一字段、是否有焦点陷阱、关闭动画是否把焦点弄丢。因变量:逃出到底层的次数、关闭后重新定位触发者的时间。读屏器应听到弹层的名称。对照已建立的对话框焦点模式做走查,测的是往返是否可逆,不是属性清单。

边界

通知气泡、短暂吐司不应抢焦点,否则正在打的字会被拽走——那是另一条「不要抢」。全屏路由式「弹层」其实是新页,关闭应走浏览历史而不是归还已卸载的按钮。嵌套弹层要归还到上一层,不是一次跳回最底层触发者。触屏没有 Tab 陷阱问题,但关闭后滚动位置和触发者仍应在视口里。

怎么落地

  • 打开弹层时把焦点送到层内(标题或首个字段),并在层内循环直到关闭。
  • 关闭时把焦点还给触发控件;控件已不在则给一个合理的附近位置并让它可见。
  • 读屏器要能听到弹层名称;不要只移动焦点不改可访问名称。
  • 验证:Tab 打开一个对话框,在层内走一圈不得掉到底下;Esc 后焦点应在原按钮上。再测读屏器是否在打开时报了层的名字。

延伸

  • 同组E2.22.1 页面加载即聚焦会打断屏幕阅读器的顺序播报 · E2.22.2 自动聚焦适合唯一且明确的首要输入框 · E2.22.4 非用户触发的焦点跳转会打断正在进行的输入
  • 相邻E4.10 模态对话框 · E4.09 抽屉
  • 站内检索dialog focus handoff · focus trap · restore focus

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/E2.22.3