对于列表中用户仍可以与之交互的“非活动”项目,我应该使用什么 aria 标签?

Joe*_*Joe 6 html accessibility wai-aria

我在可视化中有一个数据列表,我希望使其尽可能易于访问。有两个彼此相邻的列表。

列表项有两种状态。多行可以是活动的或非活动的。可以选择单行。

在一个列表中选择某项,会将“相关”项目显示为活动和非活动。请参阅下面的简化示例。用户选择了“A 2”,它链接到“B 1”和“B 4”,所以 A2 是,aria-selected但没有aria-activeor aria-inactive,我想按照演示使用aria-disabled- 但这是否表明它不可交互?用户仍然可以单击禁用的项目来选择它。

对单个“选定”项目执行多个aria-selected, 和单个操作会更好吗?aria-current=true如果用户尚未做出选择并且所有内容都处于“活动”状态,则每个项目都会处于“活动”状态,这会很奇怪吗aria-selected=true

.container {
  display: grid;
  grid-template-columns: 200px 200px
}

.list div {
  margin: 0.5rem;
  background: grey;
}

.list .selected {
  background: red;
}

.list .inactive {
  opacity: 0.3;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class="list">
    <div role="row">A 1</div>
    <div role="row" class="selected" aria-selected="true">A 2</div>
    <div role="row">A 3</div>
    <div role="row">A 4</div>
  </div>
  <div class="list">
    <div role="row">B 1</div>
    <div role="row" class="inactive" aria-disabled="true">B 2</div>
    <div role="row" class="inactive" aria-disabled="true">B 3</div>
    <div role="row">B 4</div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

评论的澄清。以下是所选项目的实际实现方式: 在此输入图像描述,它非常复杂,所以我尝试将其提炼为具体问题。

  1. 就像每个列表一样,它是可以一次选择的一对多吗?只能“选择”一项,如示例所示。多个项目被“突出显示”或“活动”。当没有选择任何内容时,它们都处于“活动”状态。
  2. 这些列表如何相互关联?它们如何与他们可能提供的内容相关联? 这些项目之间有一条样条线,相互连接,我给了它们一个role="presentation". 实际上中间有一个时间线,并且只有当时间线中的项目共享其他列表中的项目时,事物才“活动”?
  3. 如果内容发生变化以反映他们的关系,可能需要考虑诸如依赖于 aria 相关相关性的 aria 原子更新等事情? 我正在考虑这个。仅当您滚动时,项目才会发生变化,否则唯一发生变化的是活动/突出显示和选定状态。

我没有考虑过aria-label,我认为这可能是最好的解决方案,因为用户可以单击并选择非活动项目。

Sea*_*ean 2

从语义和可访问性的角度来看,我会考虑将控件与可视化本身\xe2\x80\x94 分离,至少在标记方面。这将使您可以使用更多语义输入元素,例如<input type="radio">,它们具有辅助技术可以理解的自己的状态。并且它将保持选择状态(这是一个输入元素特征)与突出显示状态(这是一个可视化显示特征)分开。

\n

然后,您可以使用以下方法将这些输入元素绑定到可视化:aria-controls

\n

为了表示可视化本身中项目的状态,我建议仅使用文本,而不是使用 ARIA 角色。

\n

一个基本的例子可以像这样工作:

\n

\r\n
\r\n
const items = document.querySelectorAll(\'.item\')\ndocument.querySelectorAll(\'input\').forEach(input => {\n  input.addEventListener(\'change\', e => {\n    let targets = e.target.dataset.controls.split(\' \')\n    items.forEach(item => {\n      let index = targets.indexOf(item.id)\n      if (-1 === index) item.dataset.state = \'inactive\'\n      else if (0 === index) item.dataset.state = \'selected\'\n      else item.dataset.state = \'highlighted\'\n    })\n  })\n})
Run Code Online (Sandbox Code Playgroud)\r\n
body {\n  display: grid;\n  grid-template: auto auto / auto auto;\n  grid-auto-flow: column;\n}\nform,\nfigure {\n  display: grid;\n  grid-template: auto/auto auto 1fr;\n  gap: 1ch;\n}\nfieldset {\n  display: grid;\n  grid-template: auto/auto auto;\n}\ninput,\nlabel {\n  cursor: pointer;\n}\nfigure,\nul {\n  padding: 0;\n  margin: 0;\n}\nul {\n  list-style: none;\n}\nli {\n  margin: 1ch 0 0 1ch;\n  padding: 1ch;\n}\nli[data-state="inactive"] {\n  background: #ddd;\n}\nli[data-state="selected"] {\n  background: #aaffaa;\n}\nli[data-state="highlighted"] {\n  background: #aaaaff;\n}\nli[data-state="inactive"] span,\nli[data-state="highlighted"] span.selected {\n  display: none;\n}\nli[data-state="selected"] span,\nli[data-state="highlighted"] span.highlighted {\n  display: inline;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<h2>Controls</h2>\n<form>\n  <fieldset>\n    <legend>List A</legend>\n    <input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3" />\n    <label for="input-A1">A1</label>\n    <input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1" />\n    <label for="input-A2">A2</label>\n    <input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4" />\n    <label for="input-A3">A3</label>\n    <input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2" />\n    <label for="input-A4">A4</label>\n  </fieldset>\n  <fieldset>\n    <legend>List B</legend>\n    <input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4" />\n    <label for="input-B1">B1</label>\n    <input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3" />\n    <label for="input-B2">B2</label>\n    <input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4" />\n    <label for="input-B3">B3</label>\n    <input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2" />\n    <label for="input-B4">B4</label>\n  </fieldset>\n</form>\n<h2>Visualization</h2>\n<figure id="graphic" aria-live="polite">\n  <ul aria-label="List A">\n    <li class="item" id="item-A1" data-state="inactive">A1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-A2" data-state="inactive">A2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-A3" data-state="inactive">A3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-A4" data-state="inactive">A4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n  </ul>\n  <ul aria-label="List B">\n    <li class="item" id="item-B1" data-state="inactive">B1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-B2" data-state="inactive">B2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-B3" data-state="inactive">B3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n    <li class="item" id="item-B4" data-state="inactive">B4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>\n  </ul>\n</figure>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

但您可能希望通过单击项目本身来直接操作可视化。如果是这样,您可以保持与第一个示例相同的结构,但在视觉上隐藏可访问的控件和文本,并在用户单击可视化中的项目时触发控件。

\n

同样,这仍然有负责控制状态\xe2\x80\x94的表单控件,它们只是在视觉上隐藏:

\n

\r\n
\r\n
const items = document.querySelectorAll(\'.item\')\ndocument.querySelectorAll(\'input\').forEach(input => {\n  input.addEventListener(\'change\', e => {\n    let targets = e.target.dataset.controls.split(\' \')\n    items.forEach(item => {\n      let index = targets.indexOf(item.id)\n      if (-1 === index) item.dataset.state = \'inactive\'\n      else if (0 === index) item.dataset.state = \'selected\'\n      else item.dataset.state = \'highlighted\'\n    })\n  })\n})\nitems.forEach(item => {\n  item.addEventListener(\'click\', e => {\n    let inputId = \'input-\' + e.target.id.split(\'-\')[1]\n    document.getElementById(inputId).click()\n  })\n})
Run Code Online (Sandbox Code Playgroud)\r\n
.sr-only {\n  border: 0;\n  clip: rect(1px, 1px, 1px, 1px);\n  -webkit-clip-path: inset(50%);\n  clip-path: inset(50%);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n  white-space: nowrap;\n}\nfigure {\n  display: grid;\n  grid-template: auto/auto auto 1fr;\n  gap: 1ch;\n}\nfigure,\nul {\n  padding: 0;\n  margin: 0;\n}\nul {\n  list-style: none;\n}\nli {\n  margin: 1ch 0 0 1ch;\n  padding: 1ch;\n  cursor: pointer;\n}\nli:hover {\n  opacity: 0.6;\n}\nli[data-state="inactive"] {\n  background: #ddd;\n}\nli[data-state="selected"] {\n  background: #aaffaa;\n}\nli[data-state="highlighted"] {\n  background: #aaaaff;\n}\nli[data-state="inactive"] span,\nli[data-state="highlighted"] span.selected {\n  display: none;\n}\nli[data-state="selected"] span,\nli[data-state="highlighted"] span.highlighted {\n  display: inline;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="sr-only">\n  <h2>Controls</h2>\n  <form>\n    <fieldset>\n      <legend>List A</legend>\n      <input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3"/>\n      <label for="input-A1">A1</label>\n      <input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1"/>\n      <label for="input-A2">A2</label>\n      <input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4"/>\n      <label for="input-A3">A3</label>\n      <input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2"/>\n      <label for="input-A4">A4</label>\n    </fieldset>\n    <fieldset>\n      <legend>List B</legend>\n      <input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4"/>\n      <label for="input-B1">B1</label>\n      <input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3"/>\n      <label for="input-B2">B2</label>\n      <input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4"/>\n      <label for="input-B3">B3</label>\n      <input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2"/>\n      <label for="input-B4">B4</label>\n    </fieldset>\n  </form>\n</div>\n<h2 class="sr-only">Visualization</h2>\n<figure id="graphic" aria-live="polite">\n  <ul aria-label="List A">\n    <li class="item" id="item-A1" data-state="inactive">A1<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-A2" data-state="inactive">A2<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-A3" data-state="inactive">A3<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-A4" data-state="inactive">A4<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n  </ul>\n  <ul aria-label="List B">\n    <li class="item" id="item-B1" data-state="inactive">B1<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-B2" data-state="inactive">B2<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-B3" data-state="inactive">B3<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n    <li class="item" id="item-B4" data-state="inactive">B4<span class="sr-only selected">, selected</span><span class="sr-only highlighted">, highlighted</span></li>\n  </ul>\n</figure>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n