对于初学者来说,无障碍性可能令人望而生畏。即使你满怀热情,要开发符合标准、完全无障碍的网站和应用程序,学习曲线仍然十分陡峭。而且很难找到正确的建议,因为这是一个不断变化且越来越拥挤的领域。
我写这篇文章是为了给你一些关于一些小事情的建议,这些小事情可以带来巨大的改变,同时希望不会影响你的开发过程太多。
让我们深入了解!
文档结构和语义
用有组织的、语义化的方式构建你的 HTML,这可能并不让人意外,它会带来很大的改变。屏幕阅读器依赖于结构良好的文档,以便遵循连贯的叙述,因此请确保你正在使用 HTML5 规范提供的元素,以便及时有效地响应。
如果你不确定如何正确地标记你的工作,请查看一些资源,例如 HTML5 Doctor、Code Academy,当然还有 CSS-Tricks。你还可以查看文章,例如 “以无障碍性为中心的 HTML 编写” 和 “语义结构”,这些文章可以帮助你朝着正确的方向前进。
让我们看看三个可以帮助确保文档结构良好和语义化的具体事项。
<main>
元素
使用单个 构建负责任的、语义化的文档结构的一个好例子是只使用一个 <main>
元素。它应该作为页面上对用户最重要的内容的标识。
为它添加一个 ID,并在主 <header>
中提供一个跳过链接,如下所示
<header role="banner">
<h1>Your main page title</h1>
<a href="#main-content">Skip to the main content</a>
</header>
<!-- Further down the document -->
<main id="main-content">
<!-- Put your main body of content in here and other really important stuff -->
</main>
这个小技巧应该能极大地帮助你的屏幕阅读器用户,因为他们可以继续跳过花哨的部分,直接进入你的重要内容。它也同样适用于键盘用户,因为他们可以跳过花哨的部分,直接进入你的重要内容。
另一个不错的做法是在跳过链接上添加一个 :focus
样式,使其可见。尝试在 GitHub.com 上按你的 Tab 键。很酷,对吧?
适当使用元素
所以,<button>
元素很难正确地设置样式,对吧?但这并不意味着你应该将你的 JavaScript 事件附加到 <div>
或 <a href="#">
上。你看,当你使用 <button>
时,你免费获得了键盘事件。你也在帮助屏幕阅读器用户,因为它会正确地宣布元素。请查看此示例
document.getElementsByTagName('button')[0].addEventListener('click', evt => {
alert('Oh, hey there!');
});
如果用户将焦点放在该按钮上并按 Enter 键,该事件就会触发。这会让你的生活和用户的生活都变得更轻松。很值得,对吧?
查看 Pen 按钮点击示例,作者 Andy Bell (@hankchizljaw) 在 CodePen 上发布。
确定你的标题层次结构
屏幕阅读器用户经常使用标题结构来浏览页面。这意味着我们应该帮助他们,为他们创建一个很好的层次结构。让我们看一个标准的博文
<main id="main-content">
<article>
<!-- The page title is up in the main <header> in this instance -->
<h2>My awesome blog post</h2>
<p>Vestibulum id ligula porta felis euismod semper.</p>
<p>Vestibulum id ligula porta felis euismod semper.</p>
<h3>A sub-section of this post</h3>
<p>Vestibulum id ligula porta felis euismod semper.</p>
<h4>A sub-section of the sub-section</h4>
<p>Vestibulum id ligula porta felis euismod semper.</p>
</article>
</main>
使用该示例,用户可以导航到“我的精彩博文”的开头,然后可以轻松地跳到子部分和嵌套子部分。他们还可以跳回到上一级。这只是帮助他们尽可能轻松地消费你所制作的内容的一种好方法。
建议页面只有一个 <h1>
元素,即使 W3C HTML5 规范 规定你可以使用多个。我个人同意只使用一个 <h1>
,但你可以使用多个,只要你遵循良好的结构和层次结构。这就是关键。
确保你的颜色对比度正确
要符合 WCAG 2.0 AA 标准,你需要使普通文本的对比度比率达到 4.5:1
。这包括你的段落、按钮、导航等。对于较大的文本,例如标题,你需要达到 3:1
的比率。我认为这应该是你的最低要求,因为使用诸如 Tota11y、Contrast 和 WebAim 对比度检查器 之类的工具,可以很容易地实现这一点。你仍然可以在你的设计中获得大量的颜色平衡和变化。
对比度如此重要的原因是,环境差异很大,你可能甚至没有考虑到,比如强烈的阳光和低质量的显示器。再加上视觉障碍或偏头痛,你可能会给你的用户带来问题。
确保对比度正确会对你的大量用户产生巨大的积极影响。
负责任的文本标签
我们都构建过一个项目列表,其中包含一个非描述性的、但视觉上吸引人的“更多”按钮,对吧?更多什么?我们需要对此更加负责,并提供一些上下文。
实现这一点的一种方法是使用 CSS 视觉隐藏描述性文本,并从屏幕阅读器中隐藏非描述性文本。使用 display: none;
很诱人,但屏幕阅读器可能会忽略设置了此属性的元素,因此我们需要更具创造性。我使用类似于这个小助手的东西
.visually-hidden {
display: block;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px);
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(1px);
white-space: nowrap;
position: absolute;
}
有了这个 CSS,我们就可以做这样的事情
<a href="/link-to-your-page">
<!-- This is hidden from a screen reader, but visible visually -->
<span aria-hidden="true">More</span>
<!-- This is visible to a screen reader, but visually hidden -->
<span class="visually-hidden">Continue reading: "Your post title here"</span>
</a>
有视力的用户只会看到“更多”,而屏幕阅读器用户会听到“继续阅读:‘你的帖子标题在这里’”。这两组用户都很满意。
你也可以通过在 <a>
标签上使用 aria-label
来实现上述功能。这会为屏幕阅读器覆盖其中的文本
<a href="/link-to-your-page" aria-label="Continue reading: 'Your post title here'">
More
</a>
用一些小的排版调整带来巨大的影响
始终牢记,有视觉障碍或学习障碍的人可能会尝试阅读你的内容,因此对你的排版进行一些小的调整会大有帮助。
文章等正文内容的最小尺寸应为 16px
(或等效单位)。同时,将 line-height
增加到大约 1.5
也是值得的。行间距可以帮助有阅读障碍的用户更好地理解你的内容。尺寸和间距的结合也适用于老年人和/或视力不好的人。即使是小的摘要和旁注内容也应该至少为 12px
(或等效单位)。低于此尺寸的任何内容都会让那些难以阅读的用户感到疏远。
另一个技巧是,如果你的内容非常复杂,则突出显示关键词和短语。这不仅有利于那些处理内容速度稍慢的用户,也有利于那些喜欢浏览文章的人,就像我一样。
最后,关于这一部分,我建议你谨慎选择字体。带有复杂连字符和装饰元素的字体可能非常分散注意力,因此,也许应该将这些字体的使用限制在主要的、大型的标题中。据建议,无衬线字体更适合有阅读障碍的人。查看 这篇文章,了解更多相关内容以及其他文本格式化技巧。
增强键盘支持
您可以做一些小调整来帮助主要使用键盘浏览网站的用户。
例如,您有一个小按钮,点击时会显示一个对话框。您应该将一个事件附加到 Escape 键,以便隐藏它。以下是一个示例代码片段
document.addEventListener('keyup', (evt) => {
if(evt.keyCode === 27) {
// Run whatever code hides your dialogue
}
});
查看 CodePen 上 Andy Bell 的示例:Escape 键演示 (@hankchizljaw)。
您可以为键盘导航用户做的另一个调整是不隐藏焦点。浏览器通过 outline
为我们提供免费的焦点状态。我知道它可能看起来很丑,但对于键盘用户来说非常有用。如果您想摆脱这种蓝色光晕,我理解—只需使用 :focus
伪选择器,以代替它添加一个明显的更改状态。
.your-element {
background: red;
}
.your-element:focus {
outline: none; /* Reset the default */
box-shadow: 0 0 0 3px black; /* A very obvious state change */
}
不要仅依赖颜色来传达状态更改
最后谈一个非常重要的问题。不应该仅依赖颜色来传达状态更改。以下是一个示例场景。
您有一个用于提交表单的按钮。您编写了一些漂亮的 JavaScript 代码,使它在发送数据时变灰。然后,它会根据状态变为绿色或红色。
对于色盲用户来说,这是一个噩梦。对于他们来说,按钮的变化可能微乎其微,以至于他们无法注意到,因此他们可能会不断点击按钮,变得非常沮丧。这不是理想的情况。
因此,与其依赖颜色,不如用一个支持按钮状态的响应状态消息来增强它。
查看 CodePen 上 Andy Bell 的示例:增强状态更改通信演示 (@hankchizljaw)。
该示例可以很好地快速告知用户发生了更改,并且颜色、文本和图标的使用清楚地传达了这种更改。在响应处理期间禁用按钮也有助于用户。
总结
这些小技巧应该会让您的用户体验到很大的改变,我希望您能深入研究您的项目并实施其中的一些技巧。
您还应该继续学习有关无障碍性的知识。我建议在 Twitter 上关注 Heydon Pickering (@heydonworks)、Scott O’Hara (@scottohara)、Laura Kalbag (@laurakalbag) 和 Rob Dobson (@rob_dodson)。我还建议您查看 Inclusive Components 和 A11y Project 等资源。
您的知识越多,您的网站和产品对更广泛的用户群体就越好。这只有好处,对吧?
太棒了,谢谢!
谢谢 Brian!我希望这能帮助您创建一些很棒的无障碍网站。
我理解只使用一个主元素,但我想知道现在在 HTML5.2 中,在一个页面上使用多个主元素被认为是有效的 HTML,这意味着什么。
据我所知,您一次只能有一个
<main>
元素可见。其他<main>
元素应该隐藏,例如:<main hidden>
。这将从屏幕阅读器中隐藏它。或者,您可以使用 CSS 并添加aria-hidden="true"
属性,如上所述。hidden
属性是隐藏元素(从视觉上和从屏幕阅读器中)的完全有效的方式,因此值得将其加入您的工具箱中。实际上,WHATWG 认为多个主元素是有效的(因此您可以在每个部分中包含标题、主体、页脚)。但他们可能会在将来更改这一点。最近有一个提议要更改这一点。
顺便说一下,据我所知,没有屏幕阅读器支持 main 标签。它们都跳到第一个 h1 元素,h1 应该直接位于主要内容之上。
CSS 属性 CLIP 已弃用,但您可以为新浏览器使用 CLIP-PATH。无论如何,很棒的文章 :)
啊,非常感谢 Miňo。看来我必须想出在将来使用
clip-path
的新方法。希望使用clip
的前提仍然对人们有用。.Bootstrap,尽管我很讨厌它,但使用 .sr-only 类来跳过导航链接
您认为这样做可以吗?我的意思是 CSS 是否符合要求,或者我只是在跳过主链接上使用 visibility: hidden 就可以了?
参考
https://a11yproject.com/posts/skip-nav-links/
https://v4-alpha.getbootstrap.com/getting-started/accessibility/#skip-navigation
https://github.com/twbs/bootstrap/blob/v4-dev/dist/css/bootstrap.css#L7365
CSS 肯定符合要求。Bootstrap 团队没有胡闹 :)
确实很巧妙的调整。微小的改变,但非常有用。谢谢。
不用客气。我希望这能帮助您帮助其他人 :)
非常好的文章 :) 当您知道可以从一开始就实施一些“快速获胜”技巧时,无障碍性的思考变得容易多了。
可能值得添加的一件事是,要注意“压缩的屏幕外文本”(https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe),当您在视觉上隐藏文本时。添加
white-space: nowrap
效果很好。很好!我会把它添加到我的阅读清单中。谢谢 :)
非常好的文章!干杯
谢谢 :)
我一直使用一个略微不同的隐藏描述类,这个类经过多年的发展
我相信(但不完全确定)clip 经历了不同的语法迭代,因此出现了 rect 的逗号版本,它捕捉了几个不同的供应商实现,然后它才被淘汰。新的 clip-path with inset 似乎正确地复制了旧的 clip 行为,并且如果您不需要回退,它就是首选。
使用高度和宽度为 0 有时可以像 display:none 那样隐藏元素,因此使用 1 像素的宽度和高度更安全。
其他属性使文本保持在页面流之外,溢出和换行行为正常。
Ailwyn 比我先一步提到了这一点,特别是
white-space: nowrap;
的声明。如果将其排除,屏幕阅读器可能会逐个字母地朗读隐藏的文本,因为它试图遵守浏览器在微小容器中换行文本的尝试。Jesse Beach 的文章中提供了更多信息:https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe非逗号 clip —
rect(1px 1px 1px 1px)
— 面向 IE6 和 IE7。谢谢您。它是一个外观很棒的类。
我过去常常自己使用绝对定位
.visually-hidden
,但我在可聚焦元素上遇到了问题,例如,当它们处于屏幕外或在overflow: scroll/auto
容器内时,视觉上隐藏的复选框。太棒了,感谢 Adrian!一些非常有用的反馈。我会根据您的反馈和其他人的反馈更新本文中的代码片段。
谢谢您!
很棒的文章!关于文本标签,使用“aria-label”相对于普通的“title”有什么优势呢?
基本上,它有可能不被屏幕阅读器读取。这篇文章比较老了,但内容很好:https://silktide.com/i-thought-title-text-improved-accessibility-i-was-wrong/
很多人不喜欢设置焦点样式,因为他们不喜欢它对键盘和鼠标焦点都适用。有一个 CSS 样式 :focus-ring,它允许你只通过键盘来设置焦点样式。目前支持度还不高,但有一个很棒的 polyfill!
我认为很多人不设置 :focus 样式是因为他们没有意识到它需要与 :hover 样式不同。我自己也曾不止一次为此争论过!
我有一个关于标题结构的问题。我读到你可以有多个 H1 标签,例如博客的主页。结构如下所示。
Main
H1
Article
Header
H1
/Header
{content}
/Article
Article
Header
H1
/Header
{content}
/Article
Article
Header
H1
/Header
{content}
/Article
/Main
这样正确吗?另外,如果你有多个 Section 标签,每个标签都可以有 H1 吗?还是你需要递增你的 H 标签?
你的标题结构应该反映内容,而不是
section
、article
等的使用情况。关于使用全h1
(甚至多个)的建议来自提出的文档大纲算法。但是,它从未在任何浏览器中实现,并且可能也不会实现。理想情况下,每个页面只有一个h1
,它应该反映页面的主题(并与title
元素对应)。话虽如此,我建议作者不要使用
section
或article
,除非它以h#
(任何合适的级别)开头。这是因为这些元素是 HTML 中的区段元素,应该具有可访问的名称,以便辅助技术向用户传达。使用h#
可以为你提供这一点。否则,你可能将这些元素用作样式钩子,这不是它们的用途。关键是层次结构。所以是的,在多个部分中有多个 H1,但确保部分内的标题遵循层次结构。
我喜欢使用一个 H1 的原因是它为你提供了主标题,然后使用 H2 来标记页面中的顶级部分。但如上所述,使用多个 H1 是完全有效的。
Andy,多个
h1
是有效的,但对于那些最依赖它的人来说,通常对用户是不友好的。我自己的可用性测试以及一般调查(参见 WebAIM 最新的屏幕阅读器用户调查,网址为 https://webaim.org/projects/screenreadersurvey7/#heading)告诉我,理想的途径是使用单个h1
。Adrian,这真是一个有用的见解。感谢你。我一直对多个
h1
持观望态度,但现在我会大力推广使用单个h1
的方法,并引用该研究 :).visually-hidden 看起来很 hacky。在 HTML 规范中真的还没有 ARIA 属性来处理这个问题吗?
感谢你发表这篇文章,它揭开了辅助功能基本知识的神秘面纱。关于“更多”按钮的 aria-label 示例向我表明了一个更通用的解决方案:如果“更多”文本对辅助技术用户来说不清楚,那么它可能对任何人都不清楚?善用浏览器的辅助功能也意味着知道何时不使用它们——网络默认情况下是可访问的,为所有用户提供一致的 UI 更简单、更好。
为什么 .visually-hidden 上有这么多属性?下面这个有什么问题吗?
.visually-hidden
类不是关于过度使用,而是关于灵活性。你可以把它放到任何地方,它不应该破坏你的布局,这就是我们想要的。ARIA 本质上是一个单独的规范,并且仅受屏幕阅读器支持,因此 ARIA 属性不会对非屏幕阅读器用户有利(除非你将它们用于 CSS 选择器)。仅视觉隐藏内容的属性是 CSS 的领域,而不是 HTML。在我看来,上述方法虽然笨拙,但尊重了关注点分离。如果你有切实的建议,请务必提出。W3C 始终欢迎来自更多开发者的反馈,特别是如果他们的想法基于实际经验。
作为块级元素,如果没有显式宽度,它仍然会占用空间。它也可能显示滚动条。它也不足以支持返回到 IE 世界。IE 部分很重要,因为许多依赖辅助技术的人由于其雇主、供应商甚至政策的支持而被迫使用 IE。
Andy Bell,感谢你的文章以及传播这些信息 :) 只是想快速提醒一下,使用仅包含 box-shadow 的焦点样式在 Windows 高对比度模式下有问题,因为它会删除任何背景和 box-shadow。结果是根本没有焦点样式。outline 和 border 仍然有效。
感谢你的反馈,Andrea——这的确需要注意。我从这个评论线程中学到了很多 :)
我希望带走的信息更多的是“我需要确保我的焦点状态是明显的”,而不是具体的 CSS 属性。不过我会把这个小提示记在心里。
在链接内部使用 aria-hidden 的示例也略有争议。屏幕阅读器可能会仍然读出它,例如 VoiceOver 在逐字导航内容时会读出“更多”。我相信其他屏幕阅读器也可能会读出它。此外,对于语音控制的辅助技术(*语音识别软件)来说,提供两种不同的文本(一种用于视觉,另一种用于理解 ARIA 的软件)可能会出现问题,并且不允许用户访问该控件,正如 ARIA 建议中明确说明的那样。
这也很好地了解到。感谢 Andrea :)
很棒的文章!
只是一个观察,在“不要只依靠颜色来传达状态变化”部分,你说的是正确的,按钮悬停时的状态变化太小了。普通按钮和悬停按钮之间的颜色差异太微妙了。
对我来说,悬停是一种状态变化 :)
Victor,你发现的很好!我已经对笔做了些调整 :)
对于
esc
键功能建议,我给出一百万个赞。对于我的残疾来说,鼠标真是太烦人了。我总是用它来关闭弹出窗口,而且如果它(或类似的快捷键)不能正常工作,我不可避免地会去通知网站所有者。我发现它也很让人沮丧。我希望这篇文章能引起所有人的注意,你会发现以后在网络上看到的例子会更少 :)
我是一个残疾人,通过语音识别操作电脑。许多流行的网站,如 Facebook、Pinterest,依赖键盘事件来执行搜索框中的代码。但是,像 Dragon NaturallySpeaking 这样的语音识别软件有时不会触发键盘或鼠标事件。当有人进行语音输入时,他们会在 Windows 上触发 Windows Journal 事件。这在 Facebook 上是一个大问题。我已经通过编写自定义代码来解决这个问题,以便在我进行语音输入时模拟键盘按键操作。但是,当我尝试使用一些宏时,它就失效了。
如果辅助功能指南中也包含对 Windows Journal 事件的监控,那就太好了。我希望它能成为 WCAG 指南的一部分。但是,我还没有看到这方面有任何进展。
我希望你能考虑这个建议的优点,然后把它包含在你的建议中。
作为一名开发人员,很难考虑这些问题。我很高兴你能发表评论,因为我今天的确学到了东西。
我建议开发人员使用
input
事件来检测输入,个人认为。我想知道这是否对你的情况有帮助,因为对于插入或删除的每个字符都会触发一个事件?我认为跳到主内容应该成为页面中第一个可聚焦的元素,而不是放在
<header>
元素内,并且在<h1>
页面标题之后,如示例所示。