ARIA(Accessible Rich Internet Applications)是一组属性,用于增强网页的可访问性,特别是对于使用屏幕阅读器等辅助技术的用户。为交互元素正确添加ARIA属性是Web开发中的重要实践,本文将详细介绍相关规范,并通过正反面示例说明如何正确实施。
HTML规范中的ARIA基础
ARIA的核心作用
ARIA主要用于:
- 为自定义控件提供语义
- 描述元素的状态和属性
- 改善键盘导航体验
- 提供实时区域更新通知
基本ARIA属性分类
- 角色(Roles):定义元素的类型(如
button
、dialog
) - 属性(Properties):描述元素的特征(如
aria-label
、aria-haspopup
) - 状态(States):表示元素的当前状态(如
aria-disabled
、aria-expanded
)
正面示例
1. 自定义按钮的正确实现
html
<!-- 正确示例 -->
<div
tabindex="0"
role="button"
aria-label="关闭对话框"
aria-pressed="false"
onclick="closeDialog()"
onkeydown="handleKeyPress(event)"
>
×
</div>
优点:
- 明确声明了
role="button"
,告知辅助技术这是一个按钮 - 提供了
aria-label
,为视觉隐藏的"×"符号提供说明 - 包含
aria-pressed
表示按钮的按压状态 - 实现了键盘事件处理
2. 导航菜单的正确实现
html
<!-- 正确示例 -->
<nav aria-label="主菜单">
<button
aria-expanded="false"
aria-controls="main-menu"
onclick="toggleMenu()"
>
菜单
</button>
<ul id="main-menu" hidden>
<li><a href="/home">首页</a></li>
<li><a href="/products">产品</a></li>
<li><a href="/contact">联系我们</a></li>
</ul>
</nav>
优点:
- 使用
aria-expanded
指示菜单状态 aria-controls
关联按钮与其控制的菜单hidden
属性与ARIA状态同步- 为
nav
添加了aria-label
3. 进度条的正确实现
html
<!-- 正确示例 -->
<div
role="progressbar"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
aria-label="文件上传进度"
>
<div style="width: 75%;"></div>
</div>
优点:
- 明确声明了
role="progressbar"
- 提供了完整的值范围信息
- 有清晰的标签说明
反面示例
1. 自定义按钮的错误实现
html
<!-- 错误示例 -->
<div onclick="submitForm()">
提交
</div>
问题:
- 缺少
role="button"
,辅助技术无法识别为按钮 - 没有键盘支持,无法通过键盘操作
- 缺少状态和属性描述
2. 标签关联的错误实现
html
<!-- 错误示例 -->
<div id="username-label">用户名</div>
<input type="text">
问题:
- 标签与输入框没有正确关联
- 应使用
<label for="input-id">
或aria-labelledby
修正方案:
html
<div id="username-label">用户名</div>
<input type="text" aria-labelledby="username-label">
3. 动态内容更新的错误处理
html
<!-- 错误示例 -->
<div id="notification"></div>
<script>
function showMessage(msg) {
document.getElementById('notification').innerText = msg;
}
</script>
问题:
- 内容更新时没有通知辅助技术
- 应使用
aria-live
区域
修正方案:
html
<div id="notification" aria-live="polite"></div>
最佳实践规范
-
优先使用原生HTML元素:能用
<button>
就不要用<div role="button">
-
确保键盘可操作性:所有交互元素必须支持键盘操作
-
正确关联标签:
- 使用
<label for="id">
或 aria-labelledby
/aria-label
- 使用
-
管理焦点:
- 对话框打开时捕获焦点
- 关闭时返回原焦点
- 使用
tabindex="-1"
管理可聚焦元素
-
实时区域:
- 对动态更新内容使用
aria-live
- 根据紧急程度选择
polite
或assertive
- 对动态更新内容使用
-
状态同步:
- 视觉状态与ARIA状态必须一致
- 如
aria-disabled
与实际的禁用状态同步
-
测试验证:
- 使用屏幕阅读器测试
- 使用自动化工具如axe-core
- 仅键盘导航测试
复杂控件实现示例
标签页(Tabs)的正确实现
html
<!-- 正确示例 -->
<div role="tablist" aria-label="产品特性">
<button
role="tab"
aria-selected="true"
aria-controls="panel-1"
id="tab-1"
tabindex="0"
>
特性一
</button>
<button
role="tab"
aria-selected="false"
aria-controls="panel-2"
id="tab-2"
tabindex="-1"
>
特性二
</button>
</div>
<div id="panel-1" role="tabpanel" aria-labelledby="tab-1" tabindex="0">
<!-- 内容 -->
</div>
<div id="panel-2" role="tabpanel" aria-labelledby="tab-2" hidden tabindex="0">
<!-- 内容 -->
</div>
关键点:
- 完整的
tablist
、tab
和tabpanel
角色结构 aria-selected
表示当前选中状态aria-controls
和aria-labelledby
建立关联- 正确的
tabindex
管理 - 非活动面板使用
hidden
属性
常见错误及避免方法
-
冗余ARIA:
html<!-- 错误 --> <button role="button">提交</button> <!-- 正确 --> <button>提交</button>
-
冲突的ARIA:
html<!-- 错误 --> <input type="checkbox" role="radio"> <!-- 正确 --> <input type="checkbox" role="checkbox">
-
缺少状态管理:
html<!-- 错误 --> <div role="checkbox">接受条款</div> <!-- 正确 --> <div role="checkbox" aria-checked="false" tabindex="0">接受条款</div>
-
忽略键盘交互:
html<!-- 错误 --> <div role="button" onclick="...">保存</div> <!-- 正确 --> <div role="button" tabindex="0" onclick="..." onkeydown="...">保存</div>
结论
为交互元素正确添加ARIA属性是创建无障碍Web应用的关键。遵循以下原则:
- 语义优先:尽可能使用原生HTML元素
- 明确角色:为自定义控件添加适当的ARIA角色
- 完整状态:提供所有必要的状态和属性信息
- 键盘支持:确保所有功能可通过键盘操作
- 持续测试:使用辅助技术验证实现效果
通过遵循这些规范,开发者可以创建出对所有人(包括残障用户)都友好且功能完善的Web应用程序。