关于何时选择 aria-describedby 而不是 aria-labelledby 是否有任何指导?

Is there any guidance on when to choose aria-describedby instead of aria-labelledby?

是否有关于何时选择 aria-describedby 而不是 aria-labelledby 的指导?

阅读关于这两个属性的 MDN 指南,我觉得它们是相似的并且可以互换。 两者似乎都表明它们可用于输入标签和其他内容,但许多合规性工具似乎不喜欢输入标签上的 aria-describeby。我讨厌盲目地应用一个特定的属性只是因为一个工具说我应该而且我更愿意知道一些具体的时间和原因

以下是 MDN 上关于两个 aria 属性的条目:

aria-labelledby attribute

aria-describedby attribute

它们确实很相似,有一个关键的区别。

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真的没有你想象的那么好

如果信息真的很重要(即元素没有它就没有意义)那么你应该改用视觉隐藏文本

我有一个

请注意,有些时候您不能使用它(即在 <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>

无论技术差异或支持水平如何(Graham 已经很好地涵盖了这一点),都存在 语义 差异。标签不是描述。在您链接到的 MDN 页面中,它指出:

A label provides essential information about an object, while a description provides extended information that the user might need.

关键的语义差异是“扩展”一词,或者 w3c puts it:

a label should be concise, where a description is intended to provide more verbose information

因此,标签用于“退出”或“取消”等控件,或简短的文本标签,例如产品名称,而描述则往往更长,包含更多细节,或提供 higher-level , 内容的一般解释。

示例:我最近一直在使用 aria-labelledby 来引用 传说 。图例只是一个列表,其中每个列表项都有一个 ID。然后,在同一页面的其他地方,在图表或 table 甚至另一个列表中,我使用 aria-labelledby 指向相应的图例项。这将图例与数据分离,并允许在多个图表、table headers、数字、图表或其他任何东西上重复使用相同的图例。

作为额外奖励,您可以 CSS select 具有给定 aria-labelledby 值的项目(使用属性 select 或例如 th:[aria-labelledby='tableLabelFurry'])并以一致的方式设置所有使用此标签的元素的样式。

下面是一些示例代码,其中显示了两个单独的 table,其 headers 来自图例:

* {
    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 和浏览器。