Angular无障碍开发:aria-expanded与aria-controls的合规用法及可选方案
Angular中*ngIf配合aria-controls的无障碍问题解决方案分析
问题背景
基础代码在无障碍验证中无错误:
<button aria-controls="t1" aria-expanded="false">Show</button> <div id="t1">Some text</div>
但使用Angular的*ngIf指令时,初始状态myBoolValue为false,被控制的<div>会被移出DOM:
<button aria-controls="t1" aria-expanded="myBoolValue">Show</button> <div *ngIf="myBoolValue" id="t1">Some text</div>
此时会触发验证错误:Error: The aria-controls attribute must point to an element in the same document.,原因是DOM中不存在id为t1的元素。
以下是对三种解决方案的分析:
方案1:添加始终存在于DOM中的外层div
代码示例:
<button aria-controls="t1" aria-expanded="myBoolValue">Show</button> <div id="t1"><div *ngIf="myBoolValue">Some text</div></div>
合规性:完全合规。外层div始终存在,aria-controls的目标元素一直有效,aria-expanded的状态和内部内容的显示/隐藏完全匹配,无障碍工具能准确识别控件与目标区域的关联,以及当前的展开状态,无障碍体验不受影响。
方案2:用display:none替代移除DOM
代码示例:
<button aria-controls="t1" aria-expanded="myBoolValue">Show</button> <div [ngClass]="{hidden: !myBoolValue}" id="t1">Some text</div>
配套CSS:
.hidden {display: none;}
合规性:合规且有效。display: none的元素仍存在于DOM中,满足aria-controls对目标元素存在性的要求;同时aria-expanded状态与元素显示状态一致,无障碍工具能正确关联控件和目标区域,且display: none的元素不会被屏幕阅读器读取,和*ngIf移除DOM的内容可达性效果一致,适配原有需求。
方案3:移除aria-controls属性
代码示例:
<button aria-expanded="myBoolValue">Show</button> <div *ngIf="myBoolValue">Some text</div>
有效性与可接受性:
- 有效性:能解决验证错误,但丢失了控件与目标区域的关联关系,屏幕阅读器用户无法直接知晓按钮控制的内容,只能通过上下文推断,无障碍体验有所降级。
- 可接受性:如果前两个方案因业务限制(如必须移除DOM减少节点、外层div影响布局样式)难以实现,方案3是可接受的兜底方案。但如果项目对无障碍要求较高,建议优先选择前两个方案;若控件与目标区域视觉紧邻、上下文关联极强,方案3可作为临时替代。
内容的提问来源于stack exchange,提问作者Haradzieniec
相关产品推荐
相关产品推荐

