ARIA: 滑块(slider)角色

slider 角色定义了一个输入控件,用户可以从给定范围内选择一个值。

描述

slider 角色用于范围输入微件,用户可以从给定的最小值和最大值中选择一个值。

slider 角色与其他范围选项的比较

ARIA 为开发者提供了六种不同的范围微件角色,包括 progressbarmeterslider

progressbar 角色,类似于 HTML 的 <progress> 元素,是一个只读范围,指示任务完成的进度,以单方向推进,例如文件上传的加载进度条,在完全加载时最终达到 100%。

meter 角色,类似于 HTML 的 <meter> 元素,是一个只读仪表,指示已知范围内某物的数量,例如计算机的电池指示器或汽车的燃油表。

slider 角色,类似于 HTML 的 input 元素中的 range 类型,<input type="range">,是一个读写输入范围。滑块允许用户在设定的最小值和最大值之间选择一个值。用户通过沿着水平或垂直滑块移动滑块拇指来选择一个值。

虽然这三个范围都具有相同的 ARIA 状态和属性,但 slider 角色是唯一一个读写范围:它是唯一一个通过用户交互改变值的角色。因此,它必须能够接收焦点。此外,必须支持键盘交互、鼠标点击和触摸交互。

警告:为了改变滑块值,基于触摸的辅助技术需要通过合成按键事件来响应用户增加和减少值的手势。在使用 slider 角色(以及所有范围微件)之前,请在以触摸作为主要输入机制的设备上使用辅助技术充分测试滑块微件。

通用属性

aria-valuemin 属性设置最小值。如果省略或不是数字,则默认为 0(零)。

aria-valuemax 属性定义最大值。如果缺失或不是数字,则默认为 100。

aria-valuenow 属性值必须在最小值和最大值之间(包括最小值和最大值)。此属性对于 slidermeter 是必需的,对于 progressbar 是可选的。

对于 slider,除非使用 <input type="range"> 元素,否则当用户更新值时,必须以编程方式更新 aria-valuenow 值。

aria-valuenow 的数值不能反映滑块的预期值时,会包含可选的 aria-valuetext 属性。由于最小值、最大值和当前值都是数字,当这些数字代表的值不是数字时,应包含 aria-valuetext 属性,其字符串值定义了该数值。例如,如果使用滑块来表示 T 恤尺码,则当 aria-valuenow 增加时,aria-valuetext 属性应从 xx-small 变为 XX-large。

aria-valuetext 值必须随着 valuearia-valuenow 的更新而更新。虽然 <input type="range"> 没有等效的 HTML 属性,但您可以在任何 <input> 类型中包含 aria-valuetext。ARIA 属性在语义 HTML 元素上受支持。

aria-valuetext 是滑块的重要功能时,请考虑改用带有 <option> 元素的 <select>。虽然在视觉上不是一个范围,但每个选项的值对所有用户都更易访问,而不仅仅是辅助技术用户。

可访问名称是必需的。如果范围的角色应用于 HTML <input> 元素(或 <meter><progress> 元素),则可访问名称可以来自关联的 <label>。否则,如果存在可见标签,则使用 aria-labelledby;如果不存在可见标签,则使用 aria-label

当不使用 HTML <input> 元素来创建滑块时,请包含 tabindex 属性以使滑块可聚焦。在这三种范围类型中,只有 slider 是用户可交互的,因此是唯一需要能够接收焦点的类型。焦点应放置在滑块拇指上。

滑块具有隐式的 aria-orientation 值为 horizontal。此属性不支持 meterprogressbar

用户交互

与只读的 meterprogressbar 角色不同,slider 是一种接受用户交互的输入。除了包含 tabindex 属性以启用滑块焦点之外,还必须实现键盘和指针设备支持。

滑块表示可能值的范围。滑块拇指沿滑块的位置表示当前值。必须支持的用户操作包括通过拖动拇指或单击滑块来更改指针设备的值,以及使用方向键(例如箭头键)来更改键盘用户的值。请参阅下面的键盘交互

注意:建议使用原生 <input type="range"> 元素而不是 slider 角色。用户代理根据当前的 value 与最小值和最大值的关系,为范围输入元素提供一个风格化的微件。当使用非语义元素时,需要使用 ARIA 属性、JavaScript 和 CSS 重新创建原生语义元素的所有功能。

带多个滑块的范围

多滑块滑块是指带有两个或多个滑块的滑块,每个滑块设置一组相关值中的一个值。例如,在产品搜索中,可以使用双滑块来让用户设置搜索的最低和最高价格限制。

在许多双滑块中,滑块不允许相互越过,例如当滑块设置范围的最小值和最大值时。例如,在价格范围选择器中,设置范围下限的滑块的最大值受设置范围上限的滑块当前值的限制。上限滑块的最小值也受下限滑块当前值的限制。

多滑块滑块中的滑块不一定依赖于其他滑块值,但直观的用户体验是必需的,因此建议避免这种反模式。

所有后代都是展示性的

有些用户界面组件,当在平台可访问性 API 中表示时,只能包含文本。可访问性 API 无法表示包含在 slider 中的语义元素。为了解决这个限制,浏览器会自动将角色 presentation 应用于任何 slider 元素的所有后代元素,因为它是不支持语义子元素的角色。

例如,考虑以下包含标题的 slider 元素。

html
<div role="slider"><h3>Temperature in Celsius</h3></div>

因为 slider 的后代是表示性的,所以以下代码是等效的

html
<div role="slider"><h3 role="presentation">Temperature in Celsius</h3></div>

从辅助技术用户的角度来看,标题不存在,因为前面的代码片段在辅助功能树中等同于以下内容:

html
<div role="slider">Temperature in Celsius</div>

关联的 WAI-ARIA 角色、状态和属性

aria-valuenow(必需)

设置为介于 aria-valueminaria-valuemax 之间的十进制值,表示滑块的当前值。

aria-valuetext

辅助技术通常将 aria-valuenow 的值显示为数字。如果这不准确,请使用 aria-valuetext 为滑块提供更易懂的值。

aria-valuemin

设置为表示最小值的十进制值,并且小于 aria-valuemax。如果不存在,默认值为 0。

aria-valuemax

设置为表示最大值的十进制值,并且大于 aria-valuemin。如果不存在,默认值为 100。

aria-labelaria-labelledby

定义字符串值或标识标记滑块元素以提供可访问名称的元素。可访问名称是必需的。

aria-orientation

指示元素的定位是水平、垂直还是未知/模糊。对于滑块,隐式值为 horizontal,但可以设置为 vertical。由于它有隐式值,因此滑块方向永远不会模糊。

键盘交互

按键 动作
右箭头和上箭头 将选定值增加一步
左箭头和下箭头 将选定值减少一步
Page Up (可选)将值增加一个大于一步的固定量
Page Down (可选)将值减少一个大于一步的固定量
Home 将滑块设置为最小值。
End 将滑块设置为最大值。

对于可选的 Page UpPage Down 键,滑块值的变化量应大于上下箭头键所做的步长变化。

示例

在下面的示例中,我们创建了一个垂直温度计,用户可以使用它来设置室温

html
<div>
  <div id="temperatureLabel">Temperature</div>
  <div id="temperatureValue">20°C</div>
  <div id="temperatureSlider">
    <div
      id="temperatureSliderThumb"
      role="slider"
      aria-labelledby="temperatureLabel"
      aria-orientation="vertical"
      tabindex="0"
      aria-valuemin="15.0"
      aria-valuemax="25.0"
      aria-valuenow="20.0"
      aria-valuetext="20 degrees Celsius"
      style="top: calc((25 - 20)*2rem - 0.5rem)"></div>
  </div>
</div>

滑块拇指的位置是最大值减去当前值乘以每度的像素高度,再减去滑块拇指高度的一半以使其居中。其余样式是静态的。

css
[id="temperatureSlider"] {
  position: relative;
  height: 20rem;
  width: 1rem;
  outline: 1px solid;
  margin: 3rem;
}

[id="temperatureSliderThumb"] {
  position: absolute;
  height: 1rem;
  width: 2rem;
  background-color: currentColor;
  left: -0.5rem;
}

为了使此示例正常工作,我们必须编写一个脚本来处理所有键盘和指针事件,包括 pointermovepointerupfocusblurkeydown 的事件监听器,并提供默认状态以及当滑块拇指和滑块获得焦点时的样式。每次释放 ArrowLeftArrowDownArrowRightArrowUpHomeEnd 以及可选的 PageDownPageUp 键时,以及当用户拖动滑块拇指或以其他方式单击温度滑块时,滑块拇指的位置、aria-valuenowaria-valuetext 值以及具有 id "temperatureValue" 的元素的内部文本都需要更新。

使用语义 HTML,这可以写成

html
<label for="temperature"> Temperature </label>
<output id="temperatureValue">20°C</output>
<input
  type="range"
  id="temperatureSlider"
  min="15"
  max="25"
  step="0.1"
  value="20"
  aria-valuetext="20 degrees celsius" />
css
#temperatureSlider {
  transform: rotate(-90deg);
}

通过使用 <input>,我们可以免费获得一个已经样式化的范围输入微件,它具有键盘焦点、焦点样式、键盘交互以及用户交互时更新的 value。我们仍然需要使用 JavaScript 来更改 aria-valuetext<output> 元素的值。

有几种方法可以使范围输入垂直。在这个例子中,我们使用了 CSS 转换

最佳实践

如果滑块描述了页面特定区域的加载进度,请包含 aria-describedby 属性以引用滑块状态,并将该区域的 aria-busy 属性设置为 true,直到加载完成。

HTML 的 <input type="range"> 隐式具有 sliderrole。不要在 <input type="range"> 元素上使用 aria-valuemaxaria-valuemin 属性;请改用 minmax。否则,任何全局 aria-* 属性和适用于滑块角色的其他 aria-* 属性。

优先使用 HTML

建议使用类型为 range 的原生 <input> 元素,即 <input type="range">,而不是 slider 角色。

规范

规范
无障碍富互联网应用程序 (WAI-ARIA)
# slider

另见