提升 24 Ways 的可访问性

Avatar of Paul Robert Lloyd
Paul Robert Lloyd

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

最近我一直在思考我的工作性质,以及我最享受工作中的哪些方面。我的工作经常会跨越设计和开发领域,无论是编辑文字、评估界面设计还是重构代码,我逐渐意识到我的兴趣在于审查和改进的工作。

我在 24 ways 的工作就是很好的例子。自从 2013 年 Drew McLellan 让我重新设计网站以来,我一直作为团队成员,帮助审查、编辑和格式化文章。 但我也能够实现我当初在发布重新设计时所 表达的愿望

我非常相信迭代,并且不认为网站会永远完成。我希望今年发布的版本能够成为基础,并且设计在未来几年会不断发展。

在过去的几年里,随着工具的改进和最佳实践的成熟,我已经调整了设计,重构了代码,并在过程中开发了 一个组件库

24 ways 主页

关注可访问性

今年我一直在听 Laura Kalbag 关于 以通用设计的方式进行可访问性 的演讲,以及 Heydon Pickering 的 Inclusive Components 博客,该博客介绍了如何以包容的心态设计和实现常见的交互模式。突然之间,棘手的可访问性问题变得更容易理解,也不再那么教条主义了。

消化了所有这些知识之后,我渴望看看 24 ways 在被放大镜审视时会表现如何。在本文中,我将介绍五个方面,我能够在这些方面进行改进

  • 页面结构
  • 元素的标记
  • 键盘导航
  • 听觉体验
  • 通用可用性

在我开始之前,我要感谢一下。在进行了一系列初始更改之后,我请我的朋友,也是可访问性专家 Francis Storr 来审查我的工作。他发现了一些额外的错误,部分原因是他在这方面的经验,也部分原因是他使用了一系列不同的辅助工具测试了网站。

重新思考页面结构

最初的设计采用的是移动优先方法。导航被降级,并放置在页面底部。为了确保它可以在非 JavaScript 场景中从页面顶部访问,我在页面顶部添加了一个 **跳过导航** 链接。如果 JavaScript 可用,这个链接会被用来显示一个导航抽屉,它会从顶部或右侧滑动进来,具体取决于视窗的宽度。这导致了以下页面结构

<header class="c-banner">…</header>
<a class="c-menu" href="#menu">Jump to menu</a>
<main class="c-main">…</main>
<nav class="c-navigation" id="menu">
  <div class="c-traverse-nav">…</div>
  <div class="c-navigation__drawer"/>…</div>
</nav>
<footer class="c-contentinfo">…</footer>

回顾起来,这在许多方面都有问题

  • 菜单按钮 (.c-menu) 不与它控制的元素 (c-navigation-drawer) 相邻。像这样在页面上移动焦点可能会令人困惑,尤其是在没有妥善管理的情况下。
  • 网站上的所有导航都分组在一起,即使每一组链接都是为了不同的目的。
  • 抽屉行为依赖于一个链接像按钮一样工作。但是,ARIA 的第一条规则 指出

    如果您可以使用一个原生 HTML 元素或属性,该元素或属性具有您所需的功能和行为,已经内置,那么请使用它,而不是重新利用一个元素,并添加一个 ARIA 角色、状态或属性来使其可访问,请务必这样做

    去年,我更新了 JavaScript,使得这个链接会被替换为一个 button,但这复杂性暗示了我的最初解决方案并不理想。

以下是今天我得出的结构

<header class="c-banner">
  …
  <a class="c-banner__skip" href="#main">Skip to content</a>
</header>
<div class="c-menu">
  <button class="c-menu__button">…</button>
  <div class="c-menu__drawer">…</div>
</div>
<main class="c-main" id="main">…</main>
<nav class="c-traverse-nav">…</nav>
<footer class="c-contentinfo">…</footer>

将导航移动到页面顶部意味着按钮和抽屉现在彼此相邻。菜单按钮不再是两面的;它现在并且始终是一个按钮。

这种方法的缺点是,每次访问新页面时都会听到导航。同样,我们可以使用一个跳过链接,但这一次它指向的是内容块 (#main)。与其对某些用户隐藏这个可聚焦元素,不如让它 在聚焦时可见

这种结构在意识形态上可能不那么纯粹,但它更实用。这成了一个反复出现的主题。实际上,由于放弃了对 HTML5 轮廓算法能够被浏览器支持的任何希望,我已经停止使用 h1 作为节标题,并遵循了建议,即 标题等级应该用来表达文档结构

改进键盘导航

作为网站上最具交互性的组件,菜单是我审查的重点,这并不奇怪。设计要求导航抽屉的行为应该像一个对话框,这是一种交互模式,它带来了一些假设。这些假设在 eBay 的 MIND 模式中详细描述,但本质上,对话框会将焦点从页面上的其他元素中转移出来,并且是模态的;只有它里面的元素可以在它打开时操作。

我之前已经拼凑了各种 JavaScript 代码来处理聚焦(在不同阶段拼凑这些代码导致了一些奇怪的错误,例如无法将焦点绘制到对话框中的第一个元素),但我忽略了指示菜单的角色。在修复了这些问题(在菜单打开时添加 role='dialog')之后,Francis 指出,屏幕阅读器仍然可以在对话框打开时访问对话框之外的链接。例如,在 macOS VoiceOver 中,按下 CTRL + OPT + CMD + L 来导航菜单中的链接,实际上会宣布页面上的所有链接。

解决方案是将对话框之外的所有内容标记为“惰性”。Rob Dodson 在他的视频 可访问的模态对话框 中对此进行了更详细的描述。实现这一点可能有点麻烦,但是一个 引入 inert 属性的提案 将使其更容易管理。与此同时,该提案提供了一个 polyfill,因此您现在可以使用此功能。

我发现,通过从常见的交互模式的角度考虑界面,以及它们应该如何运行才能被广泛理解,这帮助我避免了复杂性,并编写了更健壮的代码。实际上,进入可访问性的世界已经发现了很多有用的资源,其中有很多写得很好的 JavaScript 示例。考虑到我对 web 编程语言的复杂关系,这些资源已经证明了它们是无价的。

正确标记元素

可访问性的很大一部分取决于标记那些依靠视觉外观来传达含义的东西。就像 alt 属性允许我们描述图像一样,aria-label(及其关系) 将这种能力扩展到其他元素

导航组件,允许用户在系列中的文章之间移动。

以下是我在导航元素中使用的标记,它允许用户在系列中的前一篇文章和下一篇文章之间进行遍历

<div class="c-traverse-nav">
  <a rel="prev" href="/2016/we-need-to-talk-about-technical-debt/"
    data-sequence-title="We Need to Talk About Technical Debt">
    <svg width="20" height="20" viewBox="0 0 200 200" role="img">
      <path d="M50 100l85 85 7-7-78-78 78-78-7-7"/>
    </svg>
    <span class="u-hidden">Previous article</span>
  </a>

  <a rel="next" href="/2016/what-the-heck-is-inclusive-design/"
    data-sequence-title="What the Heck Is Inclusive Design?">
    <span class="u-hidden">Next article</span>
    <svg width="20" height="20" viewBox="0 0 200 200" role="img">
      <path d="M150 100l-85 85-7-7 78-78-78-78 7-7"/>
    </svg>
  </a>
</div>

虽然我已经为这些链接提供了文本内容,但这个组件仍然存在一些问题

  • 没有提供任何指示来表明这些链接所扮演的角色以及它们之间的关系。
  • 在 SVG 图标上使用 role='img',但不提供任何可访问名称,就如同包含没有 alt 属性的图像一样。
  • 有用的信息(在本例中是前一篇文章和下一篇文章的标题)隐藏在一个 data- 属性中。这个属性在样式表中被用来添加在悬停时以动画方式显示的“翻盖”中显示的内容
 .c-traverse-nav a[rel=prev]:hover::after {
  content: 'Previous: \A' attr(data-sequence-title);
}

.c-traverse-nav a[rel=next]:hover::after {
  content: 'Next: \A' attr(data-sequence-title);
}

在 CSS 中使用有意义的内容?这应该是一个危险信号。我修改了这个组件,如下所示

<nav class="c-traverse-nav" aria-label="Articles">
  <a rel="prev" href="/2016/what-the-heck-is-inclusive-design/"
    aria-label="Previous: We Need to Talk About Technical Debt">
    <svg width="20" height="20" viewBox="0 0 200 200" focusable="false" aria-hidden="true">
      <path d="M50 100l85 85 7-7-78-78 78-78-7-7"/>
    </svg>
  </a>

  <a rel="next" href="/2016/what-the-heck-is-inclusive-design/"
    aria-label="Next: What the Heck Is Inclusive Design?">
    <svg width="20" height="20" viewBox="0 0 200 200" focusable="false" aria-hidden="true">
      <path d="M150 100l-85 85-7-7 78-78-78-78 7-7"/>
    </svg>
  </a>
</nav>

我做的第一件事是给这组链接加上标签。我最初选择的是 Articles navigation。但是,在测试 VoiceOver 时,它会宣布:navigation, Articles navigation。由于 nav 元素已经描述了角色,我们只需要提供关于此导航类型的信息。

第二,根据 Francis 的建议,我在所有内联 SVG 标记中添加了 focusable='false'。这是由于 IE11 中的一个错误,默认情况下,SVG 是键盘可聚焦的

关于 SVG 图标的标注,我有两种选择。我可以使用 `aria-label` 将隐藏的文本内容移动到这些图标中,或者使用 `aria-hidden` 将它们从可访问性树中完全移除。在考虑第二种选择时,我意识到我可以将隐藏的文本与 `data-` 属性中的文本合并,并在 `aria-label` 属性中使用这些组合信息。突然之间,我的 CSS 变得简单多了。

.c-traverse-nav a:hover::after {
  content: attr(aria-label);
}

可访问的标记是有用的标记。

考虑听觉体验

使用屏幕阅读器浏览网站也导致我做了一些其他小的更改。例如,网站上的一些链接包含一个向右的箭头,这是使用以下 CSS 创建的视觉装饰。

.c-continue::after {
  content: ' \203A'; /* Single Right-Pointing Angle Quotation Mark */
}

但是,屏幕阅读器通常会宣布生成的內容。当这些链接被读出来时,你会听到这样的废话。

链接,更多文章来自 drew 单个向右的角括号引号.

添加 `speak: none` 没有效果(CSS 听觉属性支持很少)。但是,我可以使用 CSS 边框创建一个类似的箭头。

.c-continue::after {
  display: inline-block;
  vertical-align: middle;
  height: 0.375em;
  width: 0.375em;
  border: 0.1875em solid;
  border-color: currentColor currentColor transparent transparent;
  transform: rotate(45deg);
  content: '';
}
改进前后的继续链接。虽然它们看起来很像,但修改后的设计听起来好多了。

我还改进了文章摘要中作者姓名样式。最初,这些姓名通过将其设置为大写文本,与摘要的其余部分区分开来。Francis 指出,一些屏幕阅读器会拼写出大写字母(无论它们是否出现在 HTML 中或被 CSS 更改),如果它们没有拼写出已知的单词。例如,VoiceOver 和 NVDA 在处理 Chris Coyier 的姓氏时会遇到问题,因此他的姓名会被读成 `Chris C-O-Y-I-E-R`。简单的解决办法是使用粗体文本来区分姓名。

老实说,过去我一直有些自负,认为通过使用语义标记和渐进增强,我不需要太担心可访问性。虽然使用正确的元素,并从视觉角度以外考虑界面很重要,但这是绝对的最低要求。了解不同的辅助技术,并愿意使用它们进行测试,同样重要。

回顾一般可用性

思考可访问性也让我提高了整体可用性。

对于今年的文章集,我们不再从文章摘录中链接到作者的网站。这种历史遗留问题以前解决得很糟糕;如果你碰巧点击了作者的名字,你会被带到他们的网站,而不是你期望的文章。我们还包含了链接到文章页面上的评论部分的评论数量(评论部分本身链接到一个单独的评论页面)。疯狂!

现在,每篇文章都只有一个链接;到文章。曾经涉及在 24×3 个链接中进行标签操作的主页,现在变得不那么嘈杂,对于每个人来说都更容易导航。

其他改进包括确保网站在高度和宽度方面都是响应式的,确保导航菜单在您点击其外部时可以关闭,以及对整体性能进行审查。这些可能不被认为是可访问性改进,但我并不确定。这样说,就等于认为可访问性是一个完全独立的问题。实际上,对一组用户有益的更改通常会对所有用户都有益。


创造新事物总是会引起人们的注意和赞赏,但在改进现有事物方面存在着一种不为人知的崇高之处。虽然并非所有更改都是视觉上的,但它们可以产生同样的影响。我知道,如果我们决定今年重新设计网站,很多这些改进都不会被实施。希望这篇概述能鼓励您查看自己的项目,并思考您可能进行的类似更改。

了解问题并扩展对可用工具的了解是 Web 开发人员的基本要求。但是,不要把这些知识留到将来;如果可以,请回去修复您以前的项目。