对于列表中用户仍然可以与之交互的 'inactive' 项,我应该使用什么 aria 标签?
What aria label should I use for 'inactive' items in a list that the user can still interact with?
我在可视化中有一个数据列表,我想让它尽可能易于访问。有两个列表彼此相邻。
列表项有两种状态。多行可以是活动的或非活动的。一行可以 selected.
在一个列表中选择某项,将 'related' 项显示为活动和非活动。请参阅下面的简化示例。用户 selected“A 2”,链接到“B 1”和“B 4”,所以 A2 是 aria-selected
但没有 aria-active
或 aria-inactive
,我想使用 aria-disabled
作为演示 - 但这是否表明它不可交互?用户仍然可以点击禁用的项目然后 select 它。
在单个 'selected' 项上执行多个 aria-selected
和一个 aria-current=true
会更好吗?如果用户还没有制作 selection 并且所有内容都是 'active',那么每个项目都将是 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;
}
<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>
来自评论的澄清。以下是 selected 项的实际实现方式:
,它非常复杂,所以我试图将其提炼为具体问题。
- 就像每个列表一样,它是一对多的,一次可以 select编辑吗? 只能 'selected',就像在例子中一样。多个项目是 'highlighted' 或 'active'。当没有 selected 时,它们都是 'active'.
- 这些列表如何相互关联?他们如何与他们可能提供的内容相关联?
这些项目之间有一条样条线,相互连接,我给了他们一个
role="presentation"
。实际上中间有一个时间线,如果时间线中的项目与另一个列表中的项目共享,事情只是'active'?
- 如果内容发生变化以反映它们之间的关系,则可能需要考虑依赖于 aria 相关相关性的 aria-atomic 更新等?
我正在考虑这个。只有当你滚动时,项目才会改变,否则唯一改变的是 active/highlight 和 selected 状态。
我没有考虑 aria-label
,我认为这可能是最好的解决方案,因为用户可以单击并 select 非活动项目。
从语义和可访问性的角度来看,我会考虑将控件与可视化本身分开——至少在标记方面。这将使您可以使用更多语义输入元素,例如 <input type="radio">
,它们具有辅助技术可以理解的自己的状态。并且它将保持选择状态(这是一个输入元素特征)与突出显示状态(这是一个可视化显示特征)分开。
然后您可以使用 aria-controls
属性将这些输入元素绑定到可视化。
要在可视化本身中表示项目的状态,而不是使用 ARIA 角色,我建议只使用文本。
一个基本的例子可以像这样工作:
const items = document.querySelectorAll('.item')
document.querySelectorAll('input').forEach(input => {
input.addEventListener('change', e => {
let targets = e.target.dataset.controls.split(' ')
items.forEach(item => {
let index = targets.indexOf(item.id)
if (-1 === index) item.dataset.state = 'inactive'
else if (0 === index) item.dataset.state = 'selected'
else item.dataset.state = 'highlighted'
})
})
})
body {
display: grid;
grid-template: auto auto / auto auto;
grid-auto-flow: column;
}
form,
figure {
display: grid;
grid-template: auto/auto auto 1fr;
gap: 1ch;
}
fieldset {
display: grid;
grid-template: auto/auto auto;
}
input,
label {
cursor: pointer;
}
figure,
ul {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
li {
margin: 1ch 0 0 1ch;
padding: 1ch;
}
li[data-state="inactive"] {
background: #ddd;
}
li[data-state="selected"] {
background: #aaffaa;
}
li[data-state="highlighted"] {
background: #aaaaff;
}
li[data-state="inactive"] span,
li[data-state="highlighted"] span.selected {
display: none;
}
li[data-state="selected"] span,
li[data-state="highlighted"] span.highlighted {
display: inline;
}
<h2>Controls</h2>
<form>
<fieldset>
<legend>List A</legend>
<input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3" />
<label for="input-A1">A1</label>
<input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1" />
<label for="input-A2">A2</label>
<input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4" />
<label for="input-A3">A3</label>
<input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2" />
<label for="input-A4">A4</label>
</fieldset>
<fieldset>
<legend>List B</legend>
<input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4" />
<label for="input-B1">B1</label>
<input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3" />
<label for="input-B2">B2</label>
<input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4" />
<label for="input-B3">B3</label>
<input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2" />
<label for="input-B4">B4</label>
</fieldset>
</form>
<h2>Visualization</h2>
<figure id="graphic" aria-live="polite">
<ul aria-label="List A">
<li class="item" id="item-A1" data-state="inactive">A1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A2" data-state="inactive">A2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A3" data-state="inactive">A3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A4" data-state="inactive">A4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
</ul>
<ul aria-label="List B">
<li class="item" id="item-B1" data-state="inactive">B1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B2" data-state="inactive">B2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B3" data-state="inactive">B3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B4" data-state="inactive">B4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
</ul>
</figure>
但您可能希望通过单击项目本身直接操作可视化。如果是这样,您可以保持与第一个示例相同的结构,但在视觉上隐藏可访问的控件和文本,并在用户单击可视化中的项目时触发控件。
同样,这仍然有负责控制状态的表单控件——它们只是在视觉上被隐藏了:
const items = document.querySelectorAll('.item')
document.querySelectorAll('input').forEach(input => {
input.addEventListener('change', e => {
let targets = e.target.dataset.controls.split(' ')
items.forEach(item => {
let index = targets.indexOf(item.id)
if (-1 === index) item.dataset.state = 'inactive'
else if (0 === index) item.dataset.state = 'selected'
else item.dataset.state = 'highlighted'
})
})
})
items.forEach(item => {
item.addEventListener('click', e => {
let inputId = 'input-' + e.target.id.split('-')[1]
document.getElementById(inputId).click()
})
})
.sr-only {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
figure {
display: grid;
grid-template: auto/auto auto 1fr;
gap: 1ch;
}
figure,
ul {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
li {
margin: 1ch 0 0 1ch;
padding: 1ch;
cursor: pointer;
}
li:hover {
opacity: 0.6;
}
li[data-state="inactive"] {
background: #ddd;
}
li[data-state="selected"] {
background: #aaffaa;
}
li[data-state="highlighted"] {
background: #aaaaff;
}
li[data-state="inactive"] span,
li[data-state="highlighted"] span.selected {
display: none;
}
li[data-state="selected"] span,
li[data-state="highlighted"] span.highlighted {
display: inline;
}
<div class="sr-only">
<h2>Controls</h2>
<form>
<fieldset>
<legend>List A</legend>
<input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3"/>
<label for="input-A1">A1</label>
<input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1"/>
<label for="input-A2">A2</label>
<input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4"/>
<label for="input-A3">A3</label>
<input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2"/>
<label for="input-A4">A4</label>
</fieldset>
<fieldset>
<legend>List B</legend>
<input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4"/>
<label for="input-B1">B1</label>
<input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3"/>
<label for="input-B2">B2</label>
<input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4"/>
<label for="input-B3">B3</label>
<input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2"/>
<label for="input-B4">B4</label>
</fieldset>
</form>
</div>
<h2 class="sr-only">Visualization</h2>
<figure id="graphic" aria-live="polite">
<ul aria-label="List A">
<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>
<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>
<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>
<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>
</ul>
<ul aria-label="List B">
<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>
<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>
<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>
<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>
</ul>
</figure>
我相信您的问题的解决方案是使用标签索引。您可以在这里阅读更多相关信息:https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex
简而言之,您可以使用 tabindex="-1" 从自然 Tab 键顺序中删除一个元素,但该元素仍然可以通过调用其 focus() 方法获得焦点。
编辑:
我可能没有提到为什么需要设置 tab-index。对于可访问性,在使用交互式列表时,应该考虑这样一个事实,即 UI 也应该可以使用键盘进行导航。对于此设置,活动和非活动元素的制表符索引将有所帮助。
然而,可能应该提到使用 aria-live='polite'
(https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) 到具有动态内容的区域。这将使屏幕 reader 监视该区域的变化并宣布它。此外,您还可以使用 [role='list'] 或 [role='group'] 为筛选 readers 列表提供额外的上下文。
我在可视化中有一个数据列表,我想让它尽可能易于访问。有两个列表彼此相邻。
列表项有两种状态。多行可以是活动的或非活动的。一行可以 selected.
在一个列表中选择某项,将 'related' 项显示为活动和非活动。请参阅下面的简化示例。用户 selected“A 2”,链接到“B 1”和“B 4”,所以 A2 是 aria-selected
但没有 aria-active
或 aria-inactive
,我想使用 aria-disabled
作为演示 - 但这是否表明它不可交互?用户仍然可以点击禁用的项目然后 select 它。
在单个 'selected' 项上执行多个 aria-selected
和一个 aria-current=true
会更好吗?如果用户还没有制作 selection 并且所有内容都是 'active',那么每个项目都将是 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;
}
<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>
来自评论的澄清。以下是 selected 项的实际实现方式:
- 就像每个列表一样,它是一对多的,一次可以 select编辑吗? 只能 'selected',就像在例子中一样。多个项目是 'highlighted' 或 'active'。当没有 selected 时,它们都是 'active'.
- 这些列表如何相互关联?他们如何与他们可能提供的内容相关联?
这些项目之间有一条样条线,相互连接,我给了他们一个
role="presentation"
。实际上中间有一个时间线,如果时间线中的项目与另一个列表中的项目共享,事情只是'active'? - 如果内容发生变化以反映它们之间的关系,则可能需要考虑依赖于 aria 相关相关性的 aria-atomic 更新等? 我正在考虑这个。只有当你滚动时,项目才会改变,否则唯一改变的是 active/highlight 和 selected 状态。
我没有考虑 aria-label
,我认为这可能是最好的解决方案,因为用户可以单击并 select 非活动项目。
从语义和可访问性的角度来看,我会考虑将控件与可视化本身分开——至少在标记方面。这将使您可以使用更多语义输入元素,例如 <input type="radio">
,它们具有辅助技术可以理解的自己的状态。并且它将保持选择状态(这是一个输入元素特征)与突出显示状态(这是一个可视化显示特征)分开。
然后您可以使用 aria-controls
属性将这些输入元素绑定到可视化。
要在可视化本身中表示项目的状态,而不是使用 ARIA 角色,我建议只使用文本。
一个基本的例子可以像这样工作:
const items = document.querySelectorAll('.item')
document.querySelectorAll('input').forEach(input => {
input.addEventListener('change', e => {
let targets = e.target.dataset.controls.split(' ')
items.forEach(item => {
let index = targets.indexOf(item.id)
if (-1 === index) item.dataset.state = 'inactive'
else if (0 === index) item.dataset.state = 'selected'
else item.dataset.state = 'highlighted'
})
})
})
body {
display: grid;
grid-template: auto auto / auto auto;
grid-auto-flow: column;
}
form,
figure {
display: grid;
grid-template: auto/auto auto 1fr;
gap: 1ch;
}
fieldset {
display: grid;
grid-template: auto/auto auto;
}
input,
label {
cursor: pointer;
}
figure,
ul {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
li {
margin: 1ch 0 0 1ch;
padding: 1ch;
}
li[data-state="inactive"] {
background: #ddd;
}
li[data-state="selected"] {
background: #aaffaa;
}
li[data-state="highlighted"] {
background: #aaaaff;
}
li[data-state="inactive"] span,
li[data-state="highlighted"] span.selected {
display: none;
}
li[data-state="selected"] span,
li[data-state="highlighted"] span.highlighted {
display: inline;
}
<h2>Controls</h2>
<form>
<fieldset>
<legend>List A</legend>
<input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3" />
<label for="input-A1">A1</label>
<input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1" />
<label for="input-A2">A2</label>
<input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4" />
<label for="input-A3">A3</label>
<input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2" />
<label for="input-A4">A4</label>
</fieldset>
<fieldset>
<legend>List B</legend>
<input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4" />
<label for="input-B1">B1</label>
<input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3" />
<label for="input-B2">B2</label>
<input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4" />
<label for="input-B3">B3</label>
<input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2" />
<label for="input-B4">B4</label>
</fieldset>
</form>
<h2>Visualization</h2>
<figure id="graphic" aria-live="polite">
<ul aria-label="List A">
<li class="item" id="item-A1" data-state="inactive">A1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A2" data-state="inactive">A2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A3" data-state="inactive">A3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-A4" data-state="inactive">A4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
</ul>
<ul aria-label="List B">
<li class="item" id="item-B1" data-state="inactive">B1<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B2" data-state="inactive">B2<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B3" data-state="inactive">B3<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
<li class="item" id="item-B4" data-state="inactive">B4<span class="selected">, selected</span><span class="highlighted">, highlighted</span></li>
</ul>
</figure>
但您可能希望通过单击项目本身直接操作可视化。如果是这样,您可以保持与第一个示例相同的结构,但在视觉上隐藏可访问的控件和文本,并在用户单击可视化中的项目时触发控件。
同样,这仍然有负责控制状态的表单控件——它们只是在视觉上被隐藏了:
const items = document.querySelectorAll('.item')
document.querySelectorAll('input').forEach(input => {
input.addEventListener('change', e => {
let targets = e.target.dataset.controls.split(' ')
items.forEach(item => {
let index = targets.indexOf(item.id)
if (-1 === index) item.dataset.state = 'inactive'
else if (0 === index) item.dataset.state = 'selected'
else item.dataset.state = 'highlighted'
})
})
})
items.forEach(item => {
item.addEventListener('click', e => {
let inputId = 'input-' + e.target.id.split('-')[1]
document.getElementById(inputId).click()
})
})
.sr-only {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
figure {
display: grid;
grid-template: auto/auto auto 1fr;
gap: 1ch;
}
figure,
ul {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
li {
margin: 1ch 0 0 1ch;
padding: 1ch;
cursor: pointer;
}
li:hover {
opacity: 0.6;
}
li[data-state="inactive"] {
background: #ddd;
}
li[data-state="selected"] {
background: #aaffaa;
}
li[data-state="highlighted"] {
background: #aaaaff;
}
li[data-state="inactive"] span,
li[data-state="highlighted"] span.selected {
display: none;
}
li[data-state="selected"] span,
li[data-state="highlighted"] span.highlighted {
display: inline;
}
<div class="sr-only">
<h2>Controls</h2>
<form>
<fieldset>
<legend>List A</legend>
<input id="input-A1" type="radio" name="input" aria-controls="graphic" data-controls="item-A1 item-B2 item-B3"/>
<label for="input-A1">A1</label>
<input id="input-A2" type="radio" name="input" aria-controls="graphic" data-controls="item-A2 item-B1"/>
<label for="input-A2">A2</label>
<input id="input-A3" type="radio" name="input" aria-controls="graphic" data-controls="item-A3 item-B2 item-B3 item-B4"/>
<label for="input-A3">A3</label>
<input id="input-A4" type="radio" name="input" aria-controls="graphic" data-controls="item-A4 item-B2"/>
<label for="input-A4">A4</label>
</fieldset>
<fieldset>
<legend>List B</legend>
<input id="input-B1" type="radio" name="input" aria-controls="graphic" data-controls="item-B1 item-A2 item-A3 item-A4"/>
<label for="input-B1">B1</label>
<input id="input-B2" type="radio" name="input" aria-controls="graphic" data-controls="item-B2 item-A2 item-B3"/>
<label for="input-B2">B2</label>
<input id="input-B3" type="radio" name="input" aria-controls="graphic" data-controls="item-B3 item-A1 item-A4"/>
<label for="input-B3">B3</label>
<input id="input-B4" type="radio" name="input" aria-controls="graphic" data-controls="item-B4 item-A2"/>
<label for="input-B4">B4</label>
</fieldset>
</form>
</div>
<h2 class="sr-only">Visualization</h2>
<figure id="graphic" aria-live="polite">
<ul aria-label="List A">
<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>
<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>
<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>
<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>
</ul>
<ul aria-label="List B">
<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>
<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>
<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>
<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>
</ul>
</figure>
我相信您的问题的解决方案是使用标签索引。您可以在这里阅读更多相关信息:https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex
简而言之,您可以使用 tabindex="-1" 从自然 Tab 键顺序中删除一个元素,但该元素仍然可以通过调用其 focus() 方法获得焦点。
编辑: 我可能没有提到为什么需要设置 tab-index。对于可访问性,在使用交互式列表时,应该考虑这样一个事实,即 UI 也应该可以使用键盘进行导航。对于此设置,活动和非活动元素的制表符索引将有所帮助。
然而,可能应该提到使用 aria-live='polite'
(https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) 到具有动态内容的区域。这将使屏幕 reader 监视该区域的变化并宣布它。此外,您还可以使用 [role='list'] 或 [role='group'] 为筛选 readers 列表提供额外的上下文。