【问题标题】:Is there any guidance on when to choose aria-describedby instead of aria-labelledby?是否有关于何时选择 aria- describeby 而不是 aria-labelledby 的指导?
【发布时间】:2020-07-27 17:41:29
【问题描述】:
是否有关于何时选择 aria- describeby 而不是 aria-labelledby 的指导?
阅读关于这两个属性的 MDN 指南,我觉得它们相似且可以互换。
两者似乎都表明它们可用于输入标签和其他内容,但许多合规工具似乎不喜欢输入标签上的 aria-describeby。我讨厌仅仅因为一个工具说我应该盲目地应用一个特定的属性,而且我更愿意知道具体的时间和原因
以下是 MDN 上有关两个 aria 属性的条目:
aria-labelledby attribute
aria-describedby attribute
【问题讨论】:
标签:
accessibility
wai-aria
【解决方案1】:
它们确实非常相似,只有一个关键区别。
aria-labelledby
aria-labelledby 将覆盖任何现有标签,包括任何语义派生标签。
例如,如果您有一个<button> 并使用了aria-labelledby,则按钮文本将被您列为标签的第一项覆盖。
在下面的示例中,如果您选择按钮(在某些屏幕阅读器中使用鼠标悬停会读取按钮文本),它将读取“第一个标签”,然后是“更多信息”而不是“不会读取此文本” .
<button aria-labelledby="lbl1 lbl2">This text will not be read</button>
<p id="lbl1">first label</p>
<p id="lbl2">Further information</p>
aria-describedby
另一方面,
aria-describedby 会将链接信息作为附加信息读取。它会在按钮语义派生信息之后读取此信息。
因此在下面的示例中,它将显示“现在将读取此文本”、“第一个标签”,然后是“更多信息”。再次,您需要聚焦按钮(而不是鼠标悬停)才能看到这种行为。
<button aria-describedby="lbl1 lbl2">This text will now be read</button>
<p id="lbl1">first label</p>
<p id="lbl2">Further information</p>
限制
警告 - support for aria-labelledby and aria-describedby 真的没有你想象的那么好。
如果信息真的很重要(即元素没有它就没有意义),那么您应该改用视觉隐藏文本。
我有一个Stack Overflow answer on the class you should use for visually hidden text instead of the built in sr-only class in most libraries.
请注意,在某些情况下您不能使用此功能(即在 <select>s <option> 内,但对于基本信息,这是唯一 100% 支持的方式(所有回到IE6)
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<button>This text will now be read <span class="visually-hidden">,first label</span> <span class="visually-hidden">,Further information</span></button>
【解决方案2】:
无论技术差异或支持水平如何(格雷厄姆已经很好地涵盖了这一点),都存在语义差异。标签不是描述。在您链接到的 MDN 页面中,它声明:
标签提供有关对象的基本信息,而
描述提供了用户可能需要的扩展信息。
关键的语义差异是“扩展”这个词,或者w3c puts it:
标签应简明扼要,说明旨在提供
更详细的信息
因此,标签用于诸如“退出”或“取消”之类的控件,或简短的文本标签,例如产品名称,而描述往往更长,包含更多细节,或提供更高级别的一般解释内容。
示例:我最近一直在使用aria-labelledby 来指代一个图例。图例只是一个列表,其中每个列表项都有一个 id。然后,在同一页面的其他地方,在图表或表格中,甚至在另一个列表中,我使用aria-labelledby 指向相应的图例项。这将图例与数据分离,并允许在多个图表、表格标题、数字、图表或其他任何东西上重复使用相同的图例。
作为额外的奖励,您可以 CSS 选择具有给定 aria-labelledby 值的项目(使用属性选择器,例如 th:[aria-labelledby='tableLabelFurry']),并以一致的方式为使用此标签的所有元素设置样式。
这里有一些示例代码,显示了两个单独的表格,其标题来自图例:
* {
box-sizing:border-box;
}
html {
background:gray;
}
body {
padding: 1.5rem;
background:white;
font-family:sans-serif;
}
main[role='main'] {
width: 10rem;
max-width: 18rem;
padding: 1.5rem;
margin: auto;
background:silver;
}
table th, table td {
padding:1em;
width:10em;
border:1px solid pink;
}
ol {
margin-left:10em;
}
ol li {
display:inline-block;
padding:1em;
width:10em;
}
<h1>Two tables sharing headers (legend implementation)</h1>
<ol id="legend">
<li id="tableLabelNumLegs">Legs</li>
<li id="tableLabelFamily">Order</li>
<li id="tableLabelFurry">Furry?</li>
</ol>
<h2>woot</h2>
<table>
<caption>Common Animals</caption>
<tbody>
<tr>
<th scope="col">Name</th>
<th scope="col" aria-labeledby="tableLabelNumLegs"></th>
<th scope="col" aria-labeledby="tableLabelFamily"></th>
<th scope="col" aria-labeledby="tableLabelFurry"></th>
</tr>
<tr>
<th scope="row">Flea</th>
<td>6</td>
<td aria-labledby="test">Siphonaptera</td>
<td>A bit</td>
</tr>
<tr>
<th scope="row">Frog</th>
<td>4</td>
<td>Anura</td>
<td>No</td>
</tr>
</tbody>
</table>
<hr />
<table>
<caption>Rare animals</caption>
<tbody>
<tr>
<th scope="col">Name</th>
<th scope="col" aria-labeledby="tableLabelNumLegs"></th>
<th scope="col" aria-labeledby="tableLabelFamily"></th>
<th scope="col" aria-labeledby="tableLabelFurry"></th>
</tr>
<tr>
<th scope="row">Tiger</th>
<td>4</td>
<td>Carnivora</td>
<td>Yes</td>
</tr>
<tr>
<th scope="row">Panda</th>
<td>4</td>
<td>Carnivora</td>
<td>Yes</td>
</tr>
</tbody>
</table>
aria-describedby 可用于对内容进行一般描述。
根据规范,这两个属性都可以包含对多个 id 的引用,但如果您打算这样做,我建议您使用一系列 AT 和浏览器进行仔细测试。