广告

前端无障碍开发者必读:如何在HTML中正确使用 aria-valuenow 提升可访问性

1. 理解 aria-valuenow 的含义与作用

1-1 aria-valuenow 的基本概念

在前端无障碍开发中,aria-valuenow 用来向辅助技术传递当前控件的数值状态,适用于需要展示数值的自定义控件。屏幕阅读器会读取这个值,帮助用户理解当前进度、当前选择等信息。这是实现可感知数值的关键属性

要点是:它并不改变视觉呈现,只提供无障碍层面的语义,因此与 CSS/JS 更新同步显得尤为重要。若控件有最小值与最大值,请始终配合 aria-valuemin 和 aria-valuemax 一起使用。

<div role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="73" aria-label="资源使用情况"><span class="bar" style="width:73%;"></span>
</div>

1-2 aria-valuenow 在不同角色中的作用

对于 role="meter"role="progressbar" 等控件,aria-valuenow 直接表示当前值,帮助屏幕阅读器用户理解进度和状态。正确的组合 还需要 aria-valuemin、aria-valuemax,确保语义完整。

当控件内部值由 JavaScript 动态更新时,确保 aria-valuenow 同步变化,否则会造成无障碍信息滞后。下面的代码演示了如何绑定事件更新当前值和视图。

const slider = document.querySelector('[role="slider"]');
function update(val) {const v = Math.max(0, Math.min(100, val));slider.setAttribute('aria-valuenow', v);// 同步视图,例如移动滑块thumb的位置
}

2. 何时需要在自定义控件中使用 aria-valuenow

2-1 适用场景

在自定义控件没有固有语义的情况下,aria-valuenow 是暴露数值的手段之一。例如自绘进度条、评级组件、音量控制等,只有通过 ARIA 提供当前值,才能让辅助技术读出当前状态。

若控件本身是原生控件(如 input type="range"progress 元素),那么 aria-valuenow 的作用会减弱,因为原生控件已经包含了当前值的语义描述,开发者应优先采用原生控件。

<div role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="60" aria-label="进度"><span class="fill" style="width:60%;"></span>
</div>

2-2 与无障碍可访问性相关的注意点

为了确保可访问性,应为自定义控件提供可键盘操作,并且通过 aria-valuenow 与最小值最大值建立明确的范围关系。这样屏幕阅读器在读取状态时会更清晰

另外,避免使用只有装饰性的 ARIA 属性,务必确保 aria-valuenow 的数值与控件的实际状态同步,否则会引发混淆。

<div role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="75" aria-label="音量"><span class="thumb" style="left:75%"/>
</div>

3. 如何正确在 HTML 中使用 aria-valuenow

3-1 基本用法与搭配属性

正确使用 aria-valuenow 时,优先设置 aria-valueminaria-valuemax,以确定数值的范围。aria-valuenow 需要与 aria-label 或 aria-labelledby 一起提供可访问名称,以让屏幕阅读器在朗读时给出清晰的上下文。

对于动态更新场景,务必在更新当前值时同步更新 aria-valuenow,否则用户会看到错误信息。下面是一个简单的示例,展示包含可访问名称的自定义进度控件。

<div role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-label="加载进度"><span class="bar" style="width:40%;"></span>
</div>

3-2 动态交互中的 aria-valuenow 更新

在事件驱动的更新场景中,使用 JavaScript 更新 aria-valuenow 是常态,并且应保证视觉和文本信息的一致性。通过事件监听器调整数值后,屏幕阅读器会朗读新值,提升可感知性。

<button id="increase" aria-label="增加值">+</button>
<div id="widget" role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="10" tabindex="0">10</div><script>
document.getElementById('increase').addEventListener('click', () => {const w = document.getElementById('widget');let v = parseInt(w.getAttribute('aria-valuenow'), 10) || 0;v = Math.min(100, v + 10);w.setAttribute('aria-valuenow', v);w.textContent = v;
});
</script>

在实现中,为可访问性提供的描述信息应与控件状态保持同步,否则屏幕阅读器读出的信息可能造成误导。

为确保可访问性,还应提供键盘交互支持,使用箭头键、Home/End 键等来改变 aria-valuenow,确保屏幕阅读器用户也能以同样的方式控制控件。

前端无障碍开发者必读:如何在HTML中正确使用 aria-valuenow 提升可访问性

3-3 备注与浏览器兼容性要点

不同浏览器和屏幕阅读器对 ARIA 的支持程度略有差异,因此在设计时要进行跨浏览器测试。确保在关键功能上有可访问性回退机制,以避免因 ARIA 使用不当导致信息缺失。

<div role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-label="加载进度"><span class="bar" style="width:40%;"></span>
</div>

4. 与原生控件的对比

4-1 原生控件中的数值属性概览

原生控件如 input type="range"progressmeter,已经自带数值语义,开发者通常不需要显式设置 aria-valuenow优先使用原生控件,以获得原生可访问性行为。

当自定义控件替代原生 UI 时,才需要用到 aria-valuenow,以提供数值信息给屏幕阅读器。下面示例比较原生和自定义控件的差异。

<!-- 原生控件示例 -->
<input type="range" min="0" max="100" value="42" aria-label="音量" /><!-- 自定义控件示例(需要 aria-valuenow) -->
<div role="slider" tabindex="0" aria-valumin="0" aria-valuemax="100" aria-valuenow="42" aria-label="音量">42</div>

4-2 实践要点与风格一致性

在团队协作中,统一的 ARIA 使用模式有助于可维护性,包括命名、属性命名和事件处理的一致性。编写清晰的文档与注释,让未来的无障碍工作更易于落地。

此外,尽量让 aria-valuenow 的更新与视觉状态同步,以避免屏幕阅读器在不同刷新频率间产生错位感。

<div role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="55" aria-label="亮度" tabindex="0"><span class="thumb" style="left:55%;"></span>
</div>

5. 可访问性测试要点

5-1 使用屏幕阅读器的基础测试

在测试 aria-valuenow 时,关键是观察屏幕阅读器对当前值的朗读是否准确、是否会在控件聚焦时提示范围。开启屏幕阅读器并遍历控件,确认读出的数值与实际状态一致。

还应进行键盘导航测试,确保通过键盘激活控件时更新值,避免仅靠鼠标操作导致的无障碍断层

<div role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="88" aria-label="亮度">88</div>

5-2 使用开发者工具进行诊断

浏览器开发者工具中的无障碍树以及 aria-valuenow 的属性状态,是诊断的关键。确保在修改控件状态时,相关属性随之更新。

<div id="acc" role="meter" aria-valuemin="0" aria-valuemax="100" aria-valuenow="30" aria-label="进度"><span class="fill" style="width:30%;"></span>
</div>

广告