问题描述
为 元素提供可访问名称的方法是通过其
alt
属性.类似地,为 元素提供可访问名称的方法是通过其
元素.
如果我在 a
标签中有一个 img
标签,则链接的可访问名称就是 img
的可访问名称.但是,如果我在 a
标签中有一个 svg
,即使 svg
有,链接也没有可访问的名称.这是为什么?
这在 Lighthouse 审核和 Firefox 开发工具的辅助功能选项卡中都很明显.
我可以在链接中添加一个 aria-label,但这似乎是重复的.
解决方案 简短回答
视觉上隐藏的文本仍然是确保链接文本被读出的最可靠方式.
还有其他更简洁的方法可以做到这一点,例如在外部图像上使用 alt
属性或在内联 SVG 上使用 aria-labelledby
所以我已经包含了这些在下面的答案中.
长答案
大多数现代屏幕阅读器都不会遇到这个问题(NVDA 和 JAWS 在我的快速测试中都阅读了标题文本),但一些较旧的屏幕阅读器(包括旧版本的 NVDA、JAW 等)将无法使用.
我相信desc"的评论相当于alt"不正确,因为我 在这个关于标题与SVG 上的描述(前三行是相关的).
为了进一步扩展,这里是 W3C 在提议的规范更新中对 SVG 的说明:-
'title' 子元素代表一个短文本替代元素.
在链接上,这可以是目标的标题或描述资源;在图像或绘图对象上,它可能是一个短图形说明;在交互式内容上,它可能是一个元素使用的标签或说明;等等.
来源:https://www.w3.org/TR/SVG2/struct.html#TitleElement
‘desc’元素代表更详细的文本信息元素,如描述.这通常暴露于提供更详细信息的辅助技术,例如图形视觉外观的描述或帮助解释复杂小部件的功能.它通常不可用其他用户,因此不应用于必要的说明.
来源:https://www.w3.org/TR/SVG2/struct.html#DescElement
外部 SVG
对于外部 SVG 文件,确保读取文本的推荐方法是使用 alt
标签.这可能意味着轻微的重复,但 alt 属性可以返回到 ie4!
保持你的 title
属性,就像有人直接访问图像一样,他们仍然会得到图像所包含内容的一些描述.
内联 SVG
为此,您应该给您的 title
一个 ID.然后将 aria-labelledby
添加到周围的链接中.如我链接的问题所述,您还可以为
提供一个 ID,并根据需要链接它们.
缺点是aria-labelledby
没有您想象的那么受支持,但它完全有效并且通过了 WCAG 建议.
<svg role="img";视图框=0 0 100 100";aria-labelledby="linkText"><title id="linkText">Bracken</title><use xlink:href="/ferns_sprite.svg#bracken"></use></svg></a>
最强大的方式 - 视觉上隐藏的文本.
上述两种方法是正确的,但如果您支持 Internet Explorer(如果您关心可访问性,则应该这样做,因为 IE 在屏幕阅读器社区的使用率更高) 那么最强大的方式仍然是视觉隐藏文本.
视觉上隐藏的文本在屏幕上不可见,但仍会被屏幕阅读器读取.
请使用下面的 CSS 类隐藏文本,因为它具有 比我给出的这个答案中解释的 bootstrap sr-only 类更好的兼容性.
注意我是如何在两种情况下使用 aria-hidden=true"
完全隐藏 SVG 的,并在到期的内联 SVG 上添加 focusable=false"
到 Internet Explorer 和较旧的 Opera 浏览器,使 SVG 具有交互性.对于不完全支持 aria
的屏幕阅读器,仍然需要空的 alt=""
作为后备.
下面应该可以一直工作到 IE6,并且提供的 CSS 类应该可以在未来几年工作!
.visually-hidden {边框:0;填充:0;边距:0;位置:绝对!重要;高度:1px;宽度:1px;溢出:隐藏;剪辑:矩形(1px 1px 1px 1px);/* IE6, IE7 - 0 高度剪辑,位于可见 1px 框的右下角 */剪辑:矩形(1px,1px,1px,1px);/* 可能已弃用,但我们需要支持旧版浏览器 */剪辑路径:插入(50%);/*现代浏览器,剪辑路径从每个角落向内工作*/空白:nowrap;/* 添加一行以阻止单词混在一起(因为它们进入单独的行并且一些屏幕阅读器不理解换行符为空格 */}
<span class="visually-hidden">Bracken</span><svg role="img" viewBox="0 0 100 100" aria-hidden="true" focusable="false"><title>布雷肯</title><use xlink:href="/ferns_sprite.svg#bracken"></use></svg></a><a href="/fern"><span class="visually-hidden">Bracken</span><img src="/bracken" alt="" aria-hidden="true"/>
The way to provide an accessible name for an <img>
element is via its alt
attribute. Similarly, the way to provide an acessible name for an <svg>
element is via its <title>
element.
If I have an img
tag within an a
tag, the accessible name of the link is the accessible name of the img
. However, if I have an svg
within an a
tag, the link has has no accessible name even if the svg
does. Why is this?
This is apparent within both Lighthouse audits and also the Accessibility tab of Firefox dev tools.
<a href="/fern">
<img src="/bracken" alt="Bracken" />
</a>
<a href="/fern">
<svg role="img" viewBox="0 0 100 100">
<title>Bracken</title>
<use xlink:href="/ferns_sprite.svg#bracken"></use>
</svg>
</a>
I could add an aria-label to the link, but that seems like duplication.
解决方案 Short Answer
Visually hidden text is still the most robust way to ensure link text is read out.
There are other ways of doing this that are neater such as using the alt
attribute on an external image or aria-labelledby
on an inline SVG so I have included those in the answer below.
Long Answer
Most modern screen readers will not have a problem with this (NVDA and JAWS both read the title text in my quick test) but some older ones (including old versions of NVDA, JAWs etc.) will not work.
I believe that the comment that "desc" is the equivalent of "alt" is not correct as I explained in this answer on title vs description on SVG (the first three lines are relevant).
To further expand on this here is what the W3C says about SVGs in the proposed spec update:-
External SVGs
For external SVG files the recommended way to ensure text is read is to use alt
tags. This may mean slight duplication but alt attributes work back to ie4!
Keep your title
attribute as if someone accesses the image directly they will still get some description of what the image contains.
Inline SVGs
For this you should give your title
an ID. Then add aria-labelledby
to the surrounding link. As stated in the question I linked you can also give the <description>
an ID and link both of them if you wish.
The downside is that aria-labelledby
is not as well supported as you might think, but it is perfectly valid and passes WCAG recommendations.
<a href="/fern">
<svg role="img" viewBox="0 0 100 100" aria-labelledby="linkText">
<title id="linkText">Bracken</title>
<use xlink:href="/ferns_sprite.svg#bracken"></use>
</svg>
</a>
The most robust way - visually hidden text.
The above two ways of doing this are correct, but if you support Internet Explorer (which you should if you care about accessibility as usage of IE is higher in the screen reader community) then the most robust way is still visually hidden text.
Visually hidden text is not visible on the screen but will still be read by a screen reader.
Please use the CSS class below to hide text as it has better compatibility than bootstrap sr-only class as explained in this answer I gave.
Notice how I completely hide the SVG in both circumstances using aria-hidden="true"
and also add focusable="false"
on the inline SVG due to Internet Explorer and older Opera browsers making SVGs interactive. The empty alt=""
is still required as a fallback for screen readers that don't fully support aria
.
The below should work all the way back to IE6 and with the CSS class provided should hopefully work for several years to come!
.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 */
}
<a href="/fern">
<span class="visually-hidden">Bracken</span>
<svg role="img" viewBox="0 0 100 100" aria-hidden="true" focusable="false">
<title>Bracken</title>
<use xlink:href="/ferns_sprite.svg#bracken"></use>
</svg>
</a>
<a href="/fern">
<span class="visually-hidden">Bracken</span>
<img src="/bracken" alt="" aria-hidden="true" />
</a>
这篇关于为什么链接不带<title>包含的 <svg>因为它是可访问的名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!