无障碍入门
损伤基础知识
障碍可分为视觉障碍、听觉障碍、行动障碍、认知障碍和语言障碍。它们也可分为情境性障碍、暂时性障碍和永久性障碍。例如,在阳光明媚的户外看不清屏幕属于情境性视觉障碍;脑震荡属于暂时性认知障碍;肢体缺失则属于永久性行动障碍。
我们在构建网站内容时,需要考虑残障人士的需求。考虑到残障人士的需求,将有助于我们所有的用户。
在思考如何更好地帮助用户时,我们需要记住:
有些用户只使用键盘进行导航,因此所有交互式内容都可通过键盘访问至关重要(注意,是所有交互式内容。将标题之类的东西添加到 Tab 键顺序中可能会造成混乱,并导致难以找到所需内容……稍后会详细说明)。
任何基于声音的内容都应该有相应的视觉效果。
不要过度设计。可以考虑为认知障碍用户提供极简设计方案,以减少干扰和认知负荷。
WCAG基础知识
WCAG 为无障碍内容提供了一个基准。它围绕着四个原则构建,这些原则定义了我们内容对用户而言应该是什么样子。
网站内容应包含以下内容:
-
可感知性——确保用户无论是否存在障碍都能接收内容
-
可操作性——确保用户可以操作用户界面组件并浏览内容。
-
易于理解——确保所有用户都能理解界面,并且界面足够一致,以避免混淆。
-
稳健可靠——确保其足够稳健,能够被各种用户使用,并且能够与辅助技术配合使用。
这通常被称为 POUR。
遵循 WCAG 指南能让你的内容在可访问性方面取得很大进展。但请记住,我们创建内容是为了用户,而不是为了填写清单。请验证 Tab 键顺序(稍后会详细介绍)以及你的内容是否能与屏幕阅读器兼容(稍后会详细介绍),以确保你的页面真正可访问。用户体验远比勾选复选框重要得多。
焦点/标签顺序
用户应该能够通过键盘访问所有交互元素,特别是通过按 Tab 键。这是评估页面可访问性时首先要检查的内容。
Tab 键的顺序应该符合逻辑,从右上角到左下角。如果 CSS 将某个元素移动到了页面的其他位置,并且这影响了 Tab 键的顺序,则需要在 HTML 中移动该元素。Tab 键的顺序是基于 DOM 的。
原生 HTML 元素内置了焦点(例如,您可以自动使用 Tab 键切换到输入框和按钮元素),但很少(应该非常少见)您需要创建自定义 HTML 元素。
您可以使用属性 tabindex 添加/更改焦点行为:
-
tabindex=”-1”
- 元素将不会按照自然的 Tab 键顺序排列。
- 可以使用 focus() 方法以编程方式聚焦元素。
- 这对于屏幕外的内容非常有用,这些内容会在用户执行特定操作后出现在屏幕上(例如,仪表盘在用户点击汉堡菜单之前一直隐藏在屏幕外)。
-
tabindex=”0”
- 元素将按自然 Tab 键顺序排列
- 可以使用 focus() 方法以编程方式聚焦元素。
-
tabindex=”3”(或任何大于 0 的值)
- 这是一种反模式,请勿这样做。它会打乱 Tab 键顺序,并且会让屏幕阅读器感到非常困惑。
- 元素将按自然 Tab 键顺序排列
- 元素将跳到 Tab 键顺序的最前面
- 如果存在多个值,则排序将从大于零的最小值开始,依次向上排列。
何时实施专注行为
焦点行为应该只添加到输入控件(例如按钮和其他交互元素)。再次提醒:如果可以,最好使用原生 HTML 元素。它们提供了大量幕后功能,而使用自定义元素则需要大量额外的工作和代码才能正确实现这些功能。
通常情况下,不应将焦点行为添加到用户不与之交互的元素上。例如,不应添加到标题或段落。但如果您想要管理焦点,则另当别论。一个很好的例子是,在页面顶部设置一个工具栏,用户可以点击其中的按钮(该按钮本身已通过 Tab 键顺序获得焦点,属于原生 HTML 元素),点击后会跳转到一个标题。您可以为该标题添加一个 `tabindex="-1"` 属性,并在用户点击按钮后调用 `focus()` 方法。
没有隐藏的焦点元素
页面上不应该有任何隐藏的焦点元素。一个简单的测试方法是使用 Tab 键在页面上移动。当元素获得焦点时,它们会显示一个焦点环(您可以自定义焦点环的行为/样式,稍后会详细介绍),并且应该在页面上可见。如果焦点环消失,并且您找不到元素的位置,可以在控制台中使用 `document.activeElement` 来检查当前激活的元素。这将为您提供该元素的引用。如果该元素在页面上不可见,则需要将其从 Tab 键顺序中移除或使其可见。
没有键盘陷阱
用户不应该进入无法通过 Tab 键切换出去的界面。但有一种例外情况,即在模态框等元素上设置临时键盘陷阱,以确保用户在任务完成前无法通过 Tab 键切换出去。
实现模态键盘陷阱:示例
在 HTML 中创建一个包含某些任务(例如确认或购物车模态框)的模态框。它将具有与 JavaScript 示例中类似的类/ID。
JS:
// initialize variable to store the element users focused on before the modal popped up
let focusedElementBeforeModal;
// select the modal, model overlay, and modal toggle from the dom
const modal = document.querySelector('.modal');
const modalOverlay = document.querySelector('.modal-overlay');
const modalToggle = document.querySelector('.modal-toggle');
// when the modal toggle is clicked, we'll open the modal
modalToggle.addEventListener('click', openModal);
function openModal() {
// save current focus
focusedElementBeforeModal = document.activeElement;
// add event listeners to trap the tab key within the modal and close the modal if the overlay is clicked
modal.addEventListener('keydown', trapTabKey);
modalOverlay.addEventListener('click', closeModal);
// add event listeners too close the modal for specific items in your modal
const resumeShoppingBtn = modal.querySelector('#resumeShopping');
resumeShoppingBtn.addEventListener('click', closeModal);
// find all focusable elements in your modal
const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),
textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]';
let focusableElements = modal.querySelectorAll(focusableElementsString);
focusableElements = Array.prototype.slice.call(focusableElements);
// store first and last focusable elements to lock within
const firstTabStop = focusableElements[0];
const lastTabStop = focusableElements[focusableElements.length - 1];
// display modal and overlay
modal.style.display = 'block';
modalOverlay.style.display = 'block';
// focus first child element
firstTabStop.focus();
function trapTabKey(e) {
// check if the key pressed was tab
if (e.keyCode === 9) {
// check if it was shift + tab
if (e.shiftKey) {
// if we were already on the first, mode to last
if (document.activeElement === firstTabStop) {
e.preventDefault();
lastTabStop.focus();
}
// else if they just hit tab
} else {
// if we were already on the last element, we're going to move back to the
// first, completing the trap
if (document.activeElement === lastTabStop) {
e.preventDefault();
firstTabStop.focus();
}
}
}
// if the key they hit was esc instead of tab, we'll close the modal
if (e.keyCode === 27) {
closeModal();
}
}
}
function closeModal() {
modal.style.display = 'none';
modalOverlay.style.display = 'none';
focusedElementBeforeModal.focus();
}
使用跳转链接节省导航
应使用跳转链接,以便用户可以通过 Tab 键快速跳转到页面主要内容。这能让键盘用户和使用语音控制技术的用户更快地浏览页面。
示例代码(这只是一个入门示例,实际实现会有所不同):
HTML:
<!-- the a tag is before nav and other dom items -->
<a href="#maincontent” class=”skip-link”>Skip to main content</a>
<nav>
<!-- nav items -->
</nav>
<main id=”maincontent” tabindex=”-1”>
<!-- main content in the page -->
</main>
*请注意,主元素中的 href 和 id 相同。CSS
:
/* make sure the color stands out against the page
and the link is placed outside of the page to start */
.skip-link {
position: absolute;
top: -40px;
left: 0;
background: #BF1722;
color: white;
padding: 8px;
z-index: 100;
}
/* when focus is on the link, it will move into view */
.skip-link:focus {
top: 0;
}
这是一篇关于跳转链接的精彩文章,而该网站本身就是跳转链接和标签顺序的绝佳示例。
语义学
网页内容的一个主要目标是让用户能够以尽可能少的培训与页面互动。我们利用交互方式来构建意义。
图形可供性
用户应该能够通过观察设计来判断其功能。例如,用于点击的按钮和用于滚动的滑块通常应该符合用户的预期。如果用户无法识别按钮的功能,则说明其图形化提示不足。其他图形化用户界面提示的例子包括模仿用户在现实生活中可能看到的元素,例如复选框。用户很可能在表格或其他他们可能在不同场合填写过的表单中见过复选框。
为视障用户提供的便利
信息应以辅助技术可以访问的方式表达。
屏幕阅读器和其他辅助技术会使用辅助功能树来创建用户界面。这个辅助功能树来自浏览器。浏览器本质上是获取 DOM 树,并对其进行修改,使其对辅助技术有用。它会移除所有样式元素和仅用于视觉效果的元素,只向用户呈现他们需要的内容。
屏幕阅读器将播报元素的:
-
名称:名称标签、职称和文本替代都与名称相关。
-
角色:元素的类型(例如:按钮、复选框、文本编辑框)
-
值:用户输入的内容
-
状态(例如:复选框的选中或未选中状态、已选中状态、已折叠状态等)
标签内容
以下特性需要在HTML中实现:
-
所有输入元素都需要一个标签(以便于查找其名称)。
- 为视力正常用户和非视力正常用户都提供了可见标签。
- 我们可以使用标签来标记元素,或者将输入框包裹在标签中,两种方法都可行。
- 如果不需要可见标签,则应使用文本替代标识。
-
图片必须带有 alt 属性。
- 如果图片仅用于装饰,则 alt 标签可以留空(alt="")
- 否则,替代文字必须具有描述性。
- 如果没有 alt 参数,屏幕阅读器会出现一些奇怪的行为,例如朗读文件名。
屏幕阅读器使用技巧
当你确认网页的标签顺序正确无误后,接下来可以试试屏幕阅读器!Mac 电脑内置了名为“VoiceOver”的屏幕阅读器,可以在辅助功能设置中找到。你可以参加相关的培训课程,学习它的基本用法,我强烈建议你去看看!所有系统都有相应的屏幕阅读器,所以如果你使用的是其他系统,只需在谷歌上搜索一下,就能找到很多相关的资源。
屏幕阅读器直接读取 DOM 元素的顺序,而不是视觉顺序。修复 Tab 键顺序应该有所帮助,但对于无法聚焦的元素,可能还需要进行一些微调。
链接文本需要具有描述性。用户只需查看链接即可了解其指向的内容。屏幕阅读器能够跳转到所有链接或快速浏览内容,因此我们需要确保每个链接都清晰明了、描述准确。
页面地标:
地标对于屏幕阅读器来说非常重要,有助于快速导航。它们可以帮助用户找到页面区域的语义信息。
可以和/或应该列入的地标:
-
主要的
- 页面通常应该只有一个主要元素,其中包含页面的主要内容。
-
标题
-
页脚
-
导航
-
文章
- 独立的内容部分,例如博客文章、新闻文章等。
-
部分
- 应用程序的通用部分
- 通常,我们会在里面添加标题来补充细节。
-
旁边
- 与周围内容略有相关的内容,例如“趣味知识”栏目。
咏叹调
正如 W3C 在其页面上所述,糟糕的 ARIA 比没有 ARIA 更糟糕。如果原生 HTML 能够满足用户的需求,就不要使用 ARIA。原生元素几乎免费地提供了语义、键盘支持和焦点,而用 ARIA 实现同样的功能则需要大量的代码和时间。
ARIA 或 WAI-ARIA 代表 Web 无障碍倡议 (Web Accessibility Initiative) 的无障碍富互联网应用程序 (Accessible Rich Internet Applications)。它允许您为元素指定属性,并修改该元素在无障碍树中的转换方式。实际上,所有 aria 属性的更改都会影响无障碍树。
ARIA 不包含以下内容:
-
修改元素外观
-
修改元素的行为
-
增强专注力
-
添加键盘事件处理
ARIA角色
辅助功能中的角色用于解释特定的用户界面模式。例如,“复选框”之类的角色可以帮助屏幕阅读器用户了解如何与这段内容进行交互。提醒:HTML 本身就提供了角色,如有疑问,请坚持使用 HTML。
有关 ARIA 角色列表以及构建自定义元素时需要实现这些角色的要求,请参阅 W3。
使用 ARIA 进行标签
ARIA-label 可用于为任何具有视觉表现形式的 UI 元素添加标签,以便在需要屏幕阅读器识别时提供描述。例如,汉堡菜单可以添加 aria-label="menu"。
ARIA-labelledby 允许我们给不能用 label 标签标记的元素(例如通用 div)添加标签。
<div aria-labelledby=”label1”</div><span id=”label1”>I'm a label</span>
ARIA-labelled 不会像 label 那样提供点击功能,并且会覆盖 label 以及 aria-label。
ARIA现场直播
如果您需要提醒屏幕阅读器用户某些信息,ARIA live 提供了不错的选择。
-
aria-live=”assertive”
- 警报立即响起,中断用户正在进行的任何操作。
-
aria-live=”off”
- 您无需声明此项,这是默认状态,不会发出任何警报。
-
aria-live=”礼貌”
- 在任何正在进行的操作完成后提醒用户。
有三个属性与 aria-live 配合使用,可以微调传达给用户的信息。
-
aria-atomic:
- 指示在传达更新信息时是否应将整个区域视为一个整体。
-
与 Aria 相关:
- 指明应呈现哪些类型的变更。
- 新增内容:任何添加到实时区域的元素都具有重要意义。
- 删除:删除文本或其后代
- 文本:正在添加/更改的文本内容
- 全部:所有
-
Aria-忙碌:
- 这段时间不要发出警报,例如加载
风格
对于AA级,所有文本和图像的最小对比度要求为4.5:1。大号文本(18磅或14磅粗体)的对比度可以降低至最小3:1。
对于 AAA 级,最低要求是整体 7:1,大字 4.5:1。
我们应该预料到平均每20个用户中就有1个存在某种色觉障碍,因此,信息传递的方式不应仅仅局限于颜色。例如,图标应该采用不同的样式,而不仅仅是不同的颜色。链接与周围文本的对比度至少需要达到3:1,并且在鼠标悬停或获得焦点时,还需要额外的区分(例如添加下划线)。
响应式设计
即使您预期用户只会使用一种设备(例如台式机),也应该在设计时考虑响应式设计。当用户放大、缩小或使用不同的设计时,用户界面应该做出相应的调整,网页也应该保持良好的可用性。
-
请使用百分比、em 和 rem 代替像素。
-
使用响应式网格进行设计
- 使用 meta viewport 标签,并将宽度设置为 device-width,初始缩放比例设置为 1。
<meta name="viewport" content="width=device-width, initial-scale=1">
-
通过设置宽度,我们告诉视口宽度要与设备无关像素的宽度相匹配。
-
通过初始缩放,我们将 CSS 像素和设备无关像素的比例设置为 1:1。
-
请勿将 max-scale 设置为 1 或将 user-scalable 设置为 no。这些都是反模式。
- 确保用户界面交互元素周围有足够的间距,避免重叠,并留有足够的边距,以便用户在移动设备/触摸屏上可以点击。
-
将触摸目标的最小尺寸设置为 48 个设备无关像素。(对于较小的图标,可以包含空白边距)
-
将触摸目标周围的边距设置为至少 32 个与设备无关的像素,以避免用户在尝试点击其他元素时意外点击一个目标。
额外提示:聚焦风格
虽然这不是 ADA 合规性的要求,但这绝对是一个不错的点缀,而且也不需要花费太多精力。
在 CSS 中,您可以使用伪类 :focus 来设置所有用户都能看到的焦点环样式(要看到焦点环,您只需在页面上使用 Tab 键,它所落到的每个元素周围都会有一个圆环。如果您看不到圆环,则需要检查 Tab 键顺序)。
伪类和基本焦点环的示例:
:focus {
outline: 1px dotted #FFF
}
*不要将轮廓线设置为0。焦点元素应该很明显。
为了保持一致性,建议您使用 box-shadow 而不是 outline。此外,如果您已经为悬停效果编写了 CSS,您可以将大部分焦点添加到该 CSS 中,使其行为与悬停效果类似。
以下是如何使用悬停样式来设置焦点的示例:
/* we want both hover and focus to look similarly here, but only focus to have the ring */
button:hover, button:focus {
background: #E91E63;
color: #FFFFFF;
text-decoration: underline;
}
/* here we're taking out the outline, but replacing it with a box shadow*/
/* we only want the focus ring to display when we're focused on it, not hovering*/
button:focus {
outline: 0;
box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.8);
}
我发现非常有价值的资源/工具
MVP:
-
- 这是评估网页的重要工具。它确实有助于将成功标准与 WCAG 相结合,使评估更加简单。
-
- 这个网站信息量非常大,是很多无障碍设计理念的绝佳范例。我在这里读过的所有文章都通俗易懂,而且非常实用。
-
- 这是谷歌工程师提供的一门非常简短的免费课程。它资源丰富,能帮助你掌握网页无障碍设计的基础知识。我强烈建议你完成这门课程。
-
- 两者都是快速评估网页中简单错误和颜色对比度的绝佳工具。它们功能有限,大部分评估工作仍需手动完成,但它们是很好的起点。
-
- 本文及配套视频提供了一个很好的速查表,帮助您在了解基础知识后进行无障碍审查。
以上每个资源都链接到大量其他有用的资源。为了本文的简洁性,避免信息过载,我特意精简了列表。这五个资源绝对足以满足入门需求。
结论
我们今天讲了很多内容!这里是了解无障碍设计的绝佳起点,但请记住,无障碍设计远不止于此。如果您能从中记住一点,那就是无障碍设计的核心在于让更多用户能够访问我们的内容。它关乎用户体验,而不仅仅是勾选一个选项。
文章来源:https://dev.to/tabathaslatton/accessibility-101-3ep0