可访问的 SVG

Avatar of Heather Migliorisi
Heather Migliorisi

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

可缩放矢量图形 (SVG) 正在成为当今网络上首选的图形格式。您是否 放弃了图标字体 或将旧的 pg、gif 和 png 图形替换为 支持良好的 SVG?让我们看看这将如何影响辅助技术 (AT) 用户以及为了确保每个人都能获得良好的用户体验,需要做些什么。

图形和替代文本

在开始使用可访问的 SVG 之前,需要考虑一些有关图形、可访问性和替代文本的快速事项。

1. 有关的图形是否需要替代文本?

如果图形纯粹是装饰性的,则不需要替代文本。

所有 <img> 标签都需要 alt 属性才能有效,但该属性可以保留为空 (无空格) <img src="pathtofile.svg" alt=""> 仍然可以验证。😮

2. 图形及其周围文本的上下文是什么?

如果图形周围有文本/内容提供替代文本,则不需要额外的 alt 文本。例如

查看 CodePen 上 Heather Migliorisi (@hmig) 的笔 带有 figcaption 的 figure 的 SVG 作为 img src

当图形需要 alt 属性时,最合适的替代文本是什么(有关更多信息,请参阅示例 4)?根据图像的内容,可以采取不同的处理方式

查看 CodePen 上 Heather Migliorisi (@hmig) 的笔 带有 figcaption 的 figure 的 SVG 作为 img src

3. 图形是否有 功能?如果有,则应向用户传达

例如,不要完全按照图标的表示方式对其进行标记

错误的代码示例

<a href="http://codepen.io/username">
  <img src="codepen_icon.png" 
      alt="CodePen Logo">
</a>

为用户提供一些上下文

好的代码示例

<a href="http://codepen.io/username">
  <img src="codepen_icon.png" 
  alt="See Picked Pens">
</a>

有关更多信息,请阅读 WebAIM 的 “替代文本”文章,以全面了解可访问的图形和 WAI 关于图像的 Web 可访问性教程

以下示例是为以下内容而开发的

  1. 支持 SVG 的浏览器:IE 10+、FF、Chrome 和 Safari
  2. 最常用的屏幕阅读器:Jaws、NVDA、VoiceOver (VO) 和 Narrator

基本图像替换

对于 SVG 的最基本实现,我们有以下选项

1. SVG 作为 img src

查看 CodePen 上 Heather Migliorisi (@hmig) 的笔 SVG 作为 img src

让我们检查一下浏览器的使用情况统计数据,看看是否需要进一步操作。如果网站的用户使用的是最新版本(Safari 桌面版 9.1.1 或 iOS 版 9.3.2 或更高版本),我们可以停止在这里。

但是,如果大多数用户仍在使用旧版本的 Safari 或 iOS,我们需要将 role="img" 添加到 <img src="linktofile.svg" alt="Pixels,我超级可爱的猫" role="img"> 中。

👏 向修复了 Safari/WebKit 错误 的人致敬!

此示例可以用作基本的图像替换,但它不允许我们访问 SVG 的内容,无论是 AT 还是 CSS/JS。因此,如果我们想要更好地控制 SVG,则需要将 SVG 直接内嵌到 HTML 中。

2. 内嵌 SVG

内嵌 SVG 比使用 <use><img> 提供更可预测的结果和控制,因为 SVG 源代码直接在 DOM 中可用,而 DOM 会公开给辅助技术使用的可访问性 API。

让我们使用与 <img> 示例相同的基本 SVG,假设我们想要向眼睛添加移动效果。如果将 SVG 直接内嵌到 HTML 中,我们可以通过 JS 完成此操作。

查看 CodePen 上 Heather Migliorisi (@hmig) 的笔 基本 SVG - 猫

由于此 SVG 不包含任何描述图形的可见文本,因此我们需要通过以下方法添加替代文本(不可见)

  • <svg> 内部,添加
    • <title>SVG 的简短标题</title>
      • 必须是其父元素的第一个子元素
      • 将用作工具提示,当指向设备移到其上时显示
  • 如果需要,可以添加描述
    • 描述- 请注意,这不会被朗读器读取(已提交错误)

根据 W3C 规范,除了提供 <title> 和可能的 <desc> 之外,我们不需要为 SVG 做任何额外操作,因为它们应该可供可访问性 API 使用。不幸的是,浏览器的支持还没有完全到位(已报告以下方面的错误:ChromeFirefox)。

因此,为了确保 AT 可以访问 <title><desc>

  • 将适当的 ID 添加到 <title><desc>
    • <title id="uniqueTitleID">SVG 的标题</title>
    • <desc id="uniqueDescID">对于复杂图形,更长、更完整的描述。</desc>
  • <svg> 标签上,添加
    • aria-labelledby="uniqueTitleID uniqueDescID"(使用标题和描述 ID) - 标题和描述都包含在 aria-labelledby 中,因为它比 aria-describedby 具有更好的屏幕阅读器支持(请参阅技巧 #4)

还有一件事

  • <svg> 标签上,添加
    • role="img"(这样,SVG 不会被将 SVG 映射到组角色的浏览器遍历)

想要添加简单的动画,例如眼睛眨动?

setInterval(function blinkeyes() {
  var tl = new TimelineLite();
  tl.to(".eye", .4, {scaleY:.01, repeat:3, repeatDelay:.4, yoyo:true, transformOrigin: "50% 70%", ease:Power2.easeInOut});
  return tl; 
 }, 5000);

var master = new TimelineLite(); 
master.add(blinkeyes());

更新标题/描述,使其准确地解释图像。

<desc id="catDesc">An illustrated gray cat with bright green blinking eyes.</desc>

查看 CodePen 上 Heather Migliorisi (@hmig) 的笔 使用标题和描述的简单内嵌可访问 SVG 猫

3. 通过对象或 iframe 内嵌 SVG

错误警告 现在,我建议避免尝试使用 <object><iframe>。在与屏幕阅读器一起使用时,它们并不充分。

以下是我遇到的情况

选择您的 SVG 内嵌方法并添加 tabindex="0"

<object type="image/svg+xml" 
    data="/path-to-the-svg/filename.svg" 
    width="50%" 
    tabindex="0">
  <img src="Fallback_image.jpg" alt="alt content here">
</object>
<iframe src="/path-to-the-svg/filename.svg" 
    width="65%" 
    height="500" 
    sandbox 
    tabindex="0">
  <img src="Fallback_image.jpg" alt="alt content here">             
</iframe>

从内嵌示例中的最终 SVG 开始,我们需要将 role="img" 替换为 role="group",放在 svg 上。

<svg id="cat" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800" aria-labeledby="pixels-title pixels-desc" role="group">

从这里开始,事情就开始变得糟糕了…

在 SVG 中添加一个 <text> 元素,其中包含 <title> 的内容,以及可能的 <desc>(对于 NVDA)

<text id="nvda-title">A cute, gray cat with green eyes. Cat illustration by Heather Migliorisi.</text>

然后,添加一个类来隐藏文本的视觉效果,但保留内容以供屏幕阅读器使用。我们可以通过设置 `font-size: 0` 来实现。

.sr-only { font-size: 0; }

所以,您最终将拥有 `<title>`(以及可能 `<desc>`)和 `<text>`,它们包含相同的内容,以便同时支持 JAWS 和 NVDA。

说明

  • 无论是 `<object>` 还是 `<iframe>` 都不能在 Chrome 中使用。Chrome 会看到备用内容,因此您可以在其中添加替代文本,这将是存储相同内容的第三个(或第四个)位置。
  • JAWS 不会读取 `<text>` 内容(超出 aria-labelledby/describedby 中的内容)。

我建议(根据浏览器/屏幕阅读器支持)尽可能使用 `<img src="svg.svg>`。虽然这并不总是可行,因为 object/iframe 支持交互/动画,而 img 通常不支持,并且 回退 更难。

图标

有很多关于用 SVG 替换图标字体的文章。我很好奇,使用 SVG 作为图标是否能更容易地实现无障碍功能。这意味着:当您在主源 SVG 中使用 `<use>` 实现 SVG 时,浏览器是否会支持 `<title>`。遗憾的是,不行。但是,在图标本身中操作非常容易,我们将在下面向您展示操作方法。

创建包含图标的 SVG 文件(我喜欢使用 icomoon 来创建)并将其包含在文档中(http://codepen.io/hmig/full/OXWMLr/)后,我们需要确定网站需要的模式(图标+链接、图标+文本、只有图标等)。根据这些模式,我们可以设计出相应的替代文本应用方法。

首先,从图标生成器中获取的图标代码通常如下所示。

<svg> 
  <title>phone</title>
  <use xlink:href="#icon-phone"></use>
</svg>

示例 1:独立图标,有意义

有意义的图标需要替代文本。这种方法与“基本图像替换,内联 SVG 示例”非常相似。

  • 更新标题文本以反映图标存在的目的...假设它显示一项服务支持移动设备。
  • 在 `<svg>` 中添加 `role="img"`(因为 SVG 映射不一致,所以它并不总是被 AT 识别。例如,以下操作无效:Mac - VoiceOver + Chrome 或 Safari,Windows - NVDA + FF)。
<svg role="img"> 
  <title>Supports Mobile Devices</title>
  <use xlink:href="#icon-phone"></use>
</svg>

同样,让我们检查一下浏览器的使用情况统计数据,看看是否需要进一步操作。如果网站用户使用的是最新版本(Chrome 49.1)或更高版本,我们可以在这里停止。

但是,如果大多数用户仍然使用较旧版本的 Chrome,我们需要在 `<title>` 中添加 `id="xxxx"`,并在 `<svg>` 中添加 `aria-labelledby="xxxx"`。

👏 向修复 Chrome 错误 的人员致敬!

查看示例:示例 1:独立 SVG 图标,有意义,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

示例 2:独立图标,装饰性

装饰性图标(重复文本所传达的信息或不添加重要价值的图标)不需要替代文本,并且应该从屏幕阅读器中隐藏。在本例中,使用 `aria-hidden="true"` 隐藏 SVG。

<p>
  <svg aria-hidden="true"> 
    <title>checkmark</title>
    <use xlink:href="#icon-checkmark"></use>
  </svg> 
  Success! Your order went through.
</p>

查看示例:yJYVpa,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

示例 3:链接图标,无文本

对于没有与文本配对的链接图标,我们可以在 `<a>` 元素上使用 aria-label 来提供描述性替代文本。在 `<a>` 元素中添加 `aria-label="See Picked Pens"`。

<a href="link" aria-label="See Picked Pens">
  <svg> 
    <use xlink:href="#icon-codepen"></use>
  </svg>
</a>

查看示例:示例 3:链接图标,无文本,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

示例 4:链接图标,包含静态文本

同样,对于与文本配对的链接图标,让我们在 `<a>` 元素上使用 `aria-label` 来提供描述性替代文本。

在锚点标签上使用 `aria-label` 后,屏幕阅读器不会宣布链接内的文本。在 `<a>` 元素中添加 `aria-label="See Picked Pens"`。

<a href="link" aria-label="See Picked Pens">
  <svg> 
    <use xlink:href="#icon-codepen"></use>
  </svg>
  CodePen
</a>

查看示例:链接图标,包含静态文本,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

示例 5:链接图标,包含动态文本

假设链接文本+图标中有一个动态值。这里,我们不应该在链接上使用 `aria-label`,因为那样会导致动态文本的值丢失。在本例中,我们可以使用跨度和屏幕外文本方法。`id=”itemsInCart”` 的跨度中的数值是动态添加的元素。

  • 添加另一个跨度,包含其余的替代文本(例如,“购物车中的商品”)。
  • 在该文本上添加 `class="offscreen-text"` 以视觉上隐藏它。
  • 在 svg 上添加 `aria-hidden="true"`。
<a href="http://example.com" id="cart">
  <span id="itemsInCart">0</span>
  <span class="offscreen-text">items in your shopping cart</span>
  <svg aria-hidden="true">
    <use xlink:href="#icon-cart"></use>
  </svg>
</a>

查看示例:示例 5:链接图标,包含动态文本,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

图标示例的完整列表。

查看示例:无障碍 SVG 图标,作者是 Heather Migliorisi (@hmig),发布在 CodePen 上。

复杂图像 - 无障碍图表

我们可以使用 SVG 而不是 PNG 和 JPG,这一点很棒,尤其是在处理像图表这样的复杂网页内容时。在 `alt` 属性中提供所有这些信息将是过度的,因此为此图像(作为 png/jpg)提供替代文本将很棘手。相反,我们可以使用 SVG 并使所有这些文本都可访问!

1. 设置文件

图层顺序 - 在 Adobe Illustrator 中,图层将从下到上导出到 SVG 中。这一点很重要,因为我们希望按照键盘读取的逻辑顺序设置图层。``“JAWS”`组应该在代码中列出第一个,因此 JAWS 图层在 Illustrator 中位于最底部。

图层命名 - 命名图层是一个好主意,因为它们将被添加为导出的 SVG 的 ID。如果图层名称相同,请不要担心,ID 会相应地递增。

图层分组 - 这里要注意分组的方式。文本标签+关键项(用于颜色)和图表中的条形都包含在每个图表变体(JAWS、NVDA 等)的组中。这样设置的原因是为了方便使用屏幕阅读器进行阅读理解。在某些浏览器中,用户可以点击条形,相应的文本会读出来,或者被高亮显示。

保存/导出 - 为了安全起见,我喜欢保留两个版本的 SVG,一个用于在 Illustrator 中编辑,另一个用于代码编辑。因此,我将“另存为”用于 Illustrator 版本,并将“文件>导出>svg”用于更简洁的网页版本。

优化 - 在手动编辑 SVG 之前,最后要做的是优化它。Jake Archibald 的工具 SVGOMG 是一个非常棒的工具。添加 SVG 后,切换到“代码”视图,查看功能切换的具体操作。将“美化”设置为开启,因为我们仍然需要编辑代码,所以希望它可读。

最好等到 SVG 在设计上 100% 确定后才开始手动编辑它(添加辅助功能)。一旦我们开始手动编辑,就很难发现编辑器(Inkscape/Illustrator/等)是否无意中更改了明确添加的内容。

源代码控制 - 如果使用基于 Git 的源代码控制变体(Git、SourceTree 等),请提交 SVG。通过这些工具之一管理文件将有助于在从 Illustrator(或其他视觉编辑器)打开并保存文件后发现任何奇特/不希望出现的更改,因为 Illustrator 不理解任何代码(aria-*),它会删除/删除这些代码。

2. 让它可访问

屏幕阅读器可遍历 - 通过在 <svg> 中添加 role="group" 来确保 SVG 在所有浏览器中可遍历。根据新的 SVG 规范,它们应该映射到 graphics-document 角色。但是,该规范仍处于工作草案阶段,因此浏览器尚未实现它。

标题和描述 - 由于 SVG 中的文本元素充当标题和描述,让我们使用 aria-labelledby="graph-title” 和 aria-describedby="graph-desc". 将它们链接到 <svg> 元素。

内容清理 - 清理 Illustrator 可能创建的任何奇怪元素。例如,在以下 <text> 元素中添加了几个 <tspan>。屏幕阅读器可能会读出各个字母(“J” “a” “w” “s” “- 44%”)而不是单词(“Jaws – 44%”)。因此,删除围绕各个字母包装的非必需 <tspan>

错误示例

<text class="cls-2" transform="translate(345.49 36.45)">
  J
  <tspan x="6.23" y="0">a</tspan>
  <tspan x="14.22" y="0">w</tspan>
  <tspan x="26.51" y="0">s - 44%</tspan>
</text>

修复后的示例

<text class="cls-2" transform="translate(345.49 36.45)">
  Jaws - 44%
</text>

添加指向调查的链接 - 在内容方面,由于此图表是基于调查的,让我们链接到它。目前(这不是 SVG 2 中的要求),在 SVG 中,将 xlink: 添加到 href

<a xlink:href="http://webaim.org/projects/screenreadersurvey6/#used">

有关 xlink 的更多信息,请查看 Dudley Storey 的 “We’ll Always Have Paris: Using SVG Namespacing and XLink”

添加语义角色 - 为包含条形、标签和键的组添加一些语义角色。让我们将包含所有这些内容的组设为列表,因为大多数屏幕阅读器会宣布列表中的项目总数以及当前项目在列表中的位置

<g id="bars" role="list">

内部的各个组可以是列表项

<g id="Jaws" role="listitem">

向列表添加标签 - 为 AT 用户提供有关他们正在交互的图表的更多信息。使用 aria-label="bar graph" 向包含列表的组添加一个标签。

<g id="bars" role="list" aria-label="bar graph" transform="translate(0,58)">

测试和修复 - 让我们 用屏幕阅读器测试它。正如预期的那样,屏幕阅读器会朗读标题、描述和关键列表项。但是,它还会遍历 y 轴上的百分比值、每个矩形和线条。

关于在 SVG 中隐藏元素(rect、circle、text)以防 AT 的一个快速说明 - 在 SVG 中,从屏幕阅读器“隐藏”元素的唯一方法是在它上面添加 role="presentation"。这样做会阻止元素的原生语义映射到辅助功能 API。如果您有多个要隐藏的项目,不幸的是,您不能将所有内容包装在 <g> 中并向其添加 role="presentation"。唯一能做的就是从 AT 中隐藏该元素,它的子元素仍然可以遍历。因此,我们必须在要隐藏的每个单独元素上添加 role="presentation"。从好的方面来说,新的 SVG 可访问性规范旨在减轻这种负担。没有 alt 文本的元素,例如形状,将被视为具有无或呈现角色。

隐藏形状/线条 - 通过在每个元素上添加 role="presentation" 来从屏幕阅读器中隐藏形状元素。

隐藏文本元素 - 通过添加 role="presentation"aria-hidden="true" 来从屏幕阅读器中隐藏令人困惑的文本元素(如上面以黄色突出显示的 - y 轴上的 0-50%、x/y 轴线和图表中的条形)。

查看 Heather Migliorisi(@hmig)在 CodePen 上的 Pen Accessible Complex Image – Bar Graph

屏幕阅读器演示视频

交互式图像

比可访问的图表和图形更好的选择是可访问的交互式图像。让我们看看一个简单的 Timeline 信息图表。它可以分解为:顶部的“标题”文本部分和 Timeline 部分。从那里,Timeline 分解为包含标题、图像和描述的时间段。

此示例的灵感来自 codrops,但我想看看是否可以制作一个可访问的版本。可爱的猫图标来自 iconka

让我们为它添加一些活力并为时间段设置动画。与其一次显示所有信息,不如只显示时间和活动标题圆圈。当用户与时间区域或活动圆圈交互时,其余内容将被显示。

1. 设置文件

首先,按照本文前面介绍的“设置文件”部分操作。从 Web 优化的版本开始,让我们跳过 css 动画部分的设置,直接进入使其可访问的操作。

2. 使其可访问

在以下示例中,为了简化代码,已删除样式属性,但在实际演示中存在。

屏幕阅读器可遍历 - 确保 SVG 在所有浏览器中可遍历,因此在 <svg> 中添加 role="group"

<svg id="InteractiveSVG" role="group">

标题和描述 - 对于此示例,我们可以使用 SVG <g id="timeline-title"> 顶部的文本作为标题,并通过在 <svg> 中添加 aria-labelledby 来将其链接。

<svg id="InteractiveSVG" aria-labelledby="timeline-title" aria-describedby="timeline-desc" role="group">

然后,在 <desc> 中添加一个 ID,并使用 <svg> 上的 aria-describedby 将其链接起来。

<desc id="timeline-desc">An Interactive Timeline</desc>
<svg id="InteractiveSVG" aria-labelledby="timeline-title" aria-describedby="timeline-desc" role="group">

添加语义角色 - 为包含 Timeline 和时间段的组添加一些语义角色。让我们将包含所有这些内容的组设为列表:<g id="timeline" role="list">

向列表添加一个标签:<g id="timeline" role="list" aria-label="the timeline, from morning to night">

内部的各个分组时间段可以是列表项:<g id="play" role="listitem">

交互式/键盘可访问 - 在每个具有 role="listitem"<g> 之后立即添加一个 <a xlink:href></a>,以便它包含整个组。目前,这是向 SVG 添加交互性的唯一方法。

添加 tabindex="0" 以确保它在所有浏览器中都可聚焦。

<a xlink:href="#play-group" tabindex="0" id="play-group"></a>

修复链接的语义 - 注意链接指向自身。这实际上不是一个语义链接,因为它没有链接到任何东西,可能会让屏幕阅读器用户感到困惑。因此,让我们添加一个 role="img" 来表示它是一个图像元素,而不是链接。

<a xlink:href="#play-group" role="img" id="play-group"></a>

使时间段内的文本可访问 - 添加 img 角色会阻止 AT 遍历其余元素,因此我们需要添加 aria-labelledby,其中包含文本元素的 ID,顺序应与它们读取的顺序一致。

<a xlink:href="#play-group" role="img" aria-labelledby="play-time play-text" tabindex="0" id="play-group"></a>

为图像添加隐藏的描述性文本 - 使用带有 offscreen 类别的 <tspan>,以便从视觉上隐藏它,但它仍然保留在 DOM 中。

<tspan class="offscreen" id="play-description">A gray kitten tangled in a ball of yarn.</tspan>

添加 ID 到 xlink 上的 aria-labelledby,以便读取它。

<a xlink:href="#play-group" role="img" aria-labelledby="play-time play-text play-description" tabindex="0" id="play-group"></a>

设置焦点的视觉 CSS - 为使用键盘导航的人设置焦点的视觉表示是必要的。我喜欢它的外观,所以我将其也添加到悬停状态。

a:focus [class*="time-circle"], a:hover [class*="time-circle"] {
  stroke: black;
  stroke-width: 5;
  paint-order: stroke;
}

为窗口焦点添加 JavaScript - 对于 SVG,当您遍历链接项时,窗口并不总是会移动以确保元素在视窗内。原因是某些浏览器(已提交错误报告,希望很快得到修复)会滚动整个 <svg> 元素,而不考虑可能在屏幕外的子元素。因此,让我们添加一些 JavaScript 来滚动窗口,以确保聚焦的元素可见。

可能还有更有效的方法,但这只是一个快速示例

$("#play-group").focus(function() {
  window.scrollTo(250,350);
});
...
$("#cuddle-group" ).focus(function(){
  window.scrollTo(250 , 1350);
});

查看 Heather Migliorisi(@hmig)在 CodePen 上的 Pen Accessible Interactive SVG

屏幕阅读器演示视频

SVG 和高对比度模式

另一个难题:Windows 和高对比度模式。视力障碍者使用此功能来提高内容的可读性。它很麻烦,因为在使用此功能时,文本和文档主体可能会在激活该功能时更改颜色,但 SVG 中的元素不会在用户选择不同的对比度模式时更新。

来自 http://disney.wikia.com/wiki/File:Alice-facepalm.jpg 的图片

好消息是:有媒体查询可以解决这个问题。

有关如何修复文章中图标部分的示例

@media screen and (-ms-high-contrast: active) {
  .icon svg {
    /* select a color that will contrast 
       well on black or white because other 
       color modes can be chosen and you 
       need a color that will work with either 
    */
    fill: green;
  }
}

/* black text on white background *.
@media screen and (-ms-high-contrast: black-on-white) {
   .icon svg {
     /* select a dark color that will 
        contrast on black 
        (#fff is too much contrast) 
     */
    fill: #333;
  }
}

/* black text on white background */
@media screen and (-ms-high-contrast: white-on-black) {
 .icon svg {
    /* select a light color that will 
       contrast on white 
       (#000 is too much contrast)
    */
    fill: #efefef;
  }
}

结论

  • 确定是否需要替代文本
    1. 如果没有,隐藏图像/SVG aria-hidden="true"
    2. 如果有
      1. 向 SVG 元素添加/链接标题和/或描述
      2. 使用角色添加语义值(例如 role="list"role="listitem"
      3. 隐藏不应该读取的图形和分组元素,使用 role="presentation"
      4. 隐藏不应该读取的文本元素,使用 role="presentation" 和 aria-hidden=”true”
  • 确定 SVG 是否可交互
    1. 如果不是 - 不做任何操作
    2. 如果有
      1. 使用 xlink 和 tabindex="0" 设置焦点
      2. 如果链接不是实际链接,请添加角色以确保它具有语义
      3. 添加 JS 用于设置窗口焦点
      4. 为焦点设置视觉 CSS:outline
  • 使用各种屏幕阅读器 + 浏览器进行测试。测试不同的对比度模式。测试键盘导航。

特别感谢

非常感谢 Amelia Bellamy-Royds 和 Leonie Watson 检查了一些示例并指出了一些问题!没有他们的帮助,我无法完成这篇文章。

在撰写这篇文章时提交的错误 \o/

微软

Mozilla

在撰写这篇文章时修复的错误 👏

  • Safari/WebKit bug 需要将 role="img" 添加到 <img> 标签中
  • Chrome bug 要求你添加 aria-labelledby 或 aria-label 到 svg 中才能让标题被读取。

资源