仅靠间距实现的视觉分组不会传递给依赖顺序朗读的屏幕阅读器
别名: 语义结构 · semantic structure · DOM 分组
概念解释
接近性是最常被拿来做界面分组的线索:把几个相关字段的间距拉近、和其他内容拉开,用户一眼就能看出"这几个属于一组"。但这个效果完全建立在"看得见画面上的距离差异"这个前提上。屏幕阅读器不渲染画面、不呈现间距,它按照底层标记结构把内容转换成一段线性的语音序列,逐项念出来。如果这几个字段在标记结构里只是并排摆放、彼此之间没有任何结构上的从属或关联关系,屏幕阅读器用户听到的就是一串顺序相同、但彼此毫无关系标注的独立项目——视觉上因为间距被认作一组的信息,在朗读顺序里完全没有留下痕迹。
机制
分组之所以能在视觉上成立,是因为间距这个物理量本身携带了信息:"离得近"这件事被感知系统直接解读成"关系更密切"。这个映射关系发生在感知层面,不落在任何数据结构里——如果开发实现时只是简单地给这几个元素设置了小一点的外边距,让它们在视觉上凑在一起,而没有用任何结构去显式标注"这几个属于同一组",那么整个分组关系就只存在于渲染出来的像素间距里,没有对应的结构痕迹。屏幕阅读器读取的是这层结构,不是像素间距,结构里没有的关系,朗读顺序里自然也不会凭空出现。这正是"视觉上成组、结构上没有对应关系"这类问题最典型、也最容易被忽略的成因:视觉验收时一切正常,因为验收的人在用眼睛看;用屏幕阅读器过一遍就会发现,同一组内容和上下文中不相关的内容被念得毫无区别。
边界
如果这份视觉分组本身只是装饰性的、不承载任何理解内容所必需的关系(比如纯粹为了美观把几个已经各自有清晰标签的独立卡片拉近了一点间距),结构上没有对应关系造成的实际影响有限;但只要分组关系本身携带了理解内容必须依赖的信息——哪个说明文字对应哪个输入框、哪几个选项属于同一个单选组——结构缺失就会直接导致内容被朗读成一堆无法辨认归属的碎片,这时不能用"反正屏幕阅读器用户比例不高"来降低这个问题的优先级,因为对受影响的用户来说,这不是体验打折,而是内容完全无法理解。
怎么落地
- 任何靠间距实现的视觉分组,只要这份分组关系对理解内容是必要的,就要在标记结构里给出与之对应的显式关系——把归为一组的字段包在同一个语义容器里,或者用能表达关联的属性把它们互相指向,不能让分组关系只停留在外边距的数值上。
- 检查现有页面是否存在这个问题,最直接的办法是关闭样式表、只看纯结构下内容的先后顺序和层级关系:如果几个视觉上分成一组的内容在去掉样式后变成了一段扁平的、看不出彼此关系的列表,说明分组只做在了视觉层,没有做在结构层。
- 验证办法:用屏幕阅读器实际朗读一遍这部分内容,只凭听到的顺序判断能不能听出"这几项属于同一组、和后面的内容不是一回事";听不出来就要回去补结构,而不是假设"反正内容都读到了就行"。