J3.03.3skip link destination设计研究

跳转后焦点需真正落在目标区

别名: 锚点焦点 · skip target · 跳转后焦点

概念解释

激活跳过链接之后,键盘焦点必须落到主内容这个目标节点上,下一次 Tab 从那里开始。只把视口滚过去、焦点仍停在跳过链接上,不算跳转成功:再按 Tab,人会回到导航的下一环,税没免掉,只是屏幕晃了一下。

目标区要能接收焦点。一个不能聚焦的 <main> 常常让用户代理把焦点留在原链接,或丢到 body。滚动位置和焦点位置是两件事。

机制

href="#main" 默认做的是视口滚动。历史上,无 tabindex 的非交互元素不会成为焦点目标,所以激活后焦点仍在跳过链接。下一次 Tab 按的是「跳过链接的下一个」,也就是顶栏里的第一项——捷径被短路了。给目标加上 tabindex="-1"(可被脚本和锚点聚焦,但不插入 Tab 序列)是补上这截契约的常用办法;有的用户代理近年已能把锚点焦点移到目标,但不能假定所有组合都如此。

另一类失败:id 指错节点,滚到了侧栏或一个空的包装 div;或者主内容在跳转后才异步渲染,锚点当时还不存在,焦点无处可去。单页应用路由之后若销毁并重建 <main>,旧 id 的跳转会打到空。

怎么研究

激活跳过链接,立刻查 document.activeElement,再按一次 Tab,看落点是主内容里的第一个控件,还是导航里的某个链接。三件都记:滚动是否发生、焦点节点是谁、下一次 Tab 去哪。只看滚动会得到假阳性。

覆盖:刚加载、客户端路由一次之后、主内容延迟出现的骨架屏。这三种时刻的锚点存活状态不同。

边界

目标聚焦时不必画出和按钮一样的厚焦点环——<main> 被程序化聚焦,环可能干扰阅读。可以让容器的焦点样式更克制,但焦点必须在这个节点上。多个跳过入口(跳过导航、跳过搜索)每个都要落到自己的目标,不能都滚到页面顶端。打印预览、嵌入的阅读视图如果没有 <main>,要指定等价的内容容器,不要把跳转指向已经不在视图里的外壳。

怎么落地

  • 主内容容器设置稳定的 id,并使其可被程序化聚焦(常用 tabindex="-1")。
  • 跳过链接的 href 指向该 id;跳转后确认 activeElement 是该容器或其内部第一个有意义的控件。
  • 异步渲染主内容时,等目标存在再完成跳转,或把焦点移到随后出现的容器上。
  • 验证:激活跳过,再 Tab 一次。若焦点回到顶栏,只是滚了屏,目标没有接住焦点。

延伸

  • 同组J3.03.1 重复的导航需要跳过入口 · J3.03.2 跳转链接需在获得焦点时可见
  • 相邻J3.02 焦点顺序与焦点陷阱 · J2.08 阅读顺序 · J2.14 语义结构与标题层级
  • 站内检索skip target · tabindex="-1" · in-page fragment focus

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/J3.03.3