1、什么是可访问性?
可访问性是一种让尽可能多的用户可以使用你的网站的做法。传统上我们认为这只与残疾人士有关,但是从更广的意义上来讲,对于移动端用户、低网速用户、键盘使用者等都适用。
无障碍指南和法律
万维网联盟:万维网联盟成立之时,就把普遍的访问(Universal Access)作为它的首要任务。并在1997年成立了网页内容易访问性推动小组(WAI Web Accessibility Initiative),该组织于1999年5月5日发布了网页内容易访问性规范 1.0版(WCAG),这个规范被认为是易访问的网站开发的国际标准,其中明确建议在网站开发过程中,应该遵守易访问性的原则。目前版本为WCAG2.1,2.2版本计划2021年发布。
美国“康复法”第508条、德国关于无障碍信息技术的联邦法令、联合王国的“平等法”、意大利的“无障碍法”、澳大利亚的“残疾歧视法”等。
目前国外的一些网站做的还比较好,比如google,youtube,mdn等,国内的一些网站目前看了一下北京政府网站无障碍版,前端一些组件库运用了wai-aria。大家可以尝试用chrome的screen reader插件结合键盘访问这些网站试试效果。
2、HTML与可访问性
正确的使用HTML标签来表达正确的意图。
使用HTML语义化,不仅不会花更多的时间,而且又有以下的可访问性优点:
- 更便于开发 —你可以使HTML更易于理解,并且可以毫不费力的获得一些功能。
- 更适配移动端 — 语义化的HTML文件比非语义化的HTML文件更加轻便,并且更易于响应式开发。
- 更便于SEO优化 — 比起使用非语义化的<div>标签,搜索引擎更加重视在“标题、链接等”里面的关键字,使用语义化可使网页更容易被用户搜索到。
2.1 页面布局
创建页面布局时多用html5语义化标签,如nav, main, article, aside, section, footer等,屏幕阅读器对这些支持标签支持性还可以。滥用table布局的方式要禁止。
<header><h1>Header</h1>
</header>
<nav><!-- main navigation in here -->
</nav>
<!-- Here is our page's main content -->
<main><!-- It contains an article --><article><h2>Article heading</h2><!-- article content in here --></article><aside><h2>Related</h2><!-- aside content in here --></aside>
</main>
<!-- And here is our main footer that is used across all the pages of our website -->
<footer><!-- footer content in here -->
</footer>
2.2 文本内容
2.2.1 良好的文本结构,最好拥有标题,段落,列表等。避免打断
- 屏幕阅读器会在您浏览内容时读取每个标题,通知您标题是什么,段落是什么等。
- 它在每个元素之后停止,让你以任何适合你的速度前进。
- 你可以在许多屏幕阅读器中跳到下一个/上一个标题。
- 你还可以在许多屏幕阅读器中显示所有标题的列表,使您可以像使用便利的目录一样使用它们以查找特定内容。
2.2.2 使用通俗易懂的语言
尽量使用不太复杂的清晰语言,不要使用不必要的行话或俚语。除此之外,你应该尽量避免使用没有被屏幕阅读器清楚读出的语言和字符。
- 如果可以避免的话,不要用破折号。写 5 到 7 ,来替代 5-7。
- 展开缩写 — 写 January,来替代 Jan 。
- 展开首字母缩略词,至少一次或两次。 例如写明 “超文本标记语言”( Hypertext Markup Language),而不是直接用缩写 HTML。
2.3 语义化标签
2.3.1 按钮
按钮建议用以下写法,通常按钮,链接和表单控件,这些控件tab键可以获取焦点,回车可以跳转触发点击动作等。普通的标签增加tabindex=0允许tab键选择,但是无法用enter键触发事件需要自己写js实现。按钮建议用button,input[type=button|submit|reset],a模拟(能用前两者的最好用前两者,a标签有些浏览器不支持tab定位)等;
<!-- 按钮建议用法 -->
<button type="button">按钮</button>
<button type="submit">按钮</button>
<input type="submit" value="按钮"/>
<a href="javascript:;" role="button">test button click</a><!-- 不建议使用非button类标签-->
<div class="button" tabindex=0>按钮</div>
重新建立键盘的可访问性
普通的标签正常情况是不能被tab键聚焦的,但是加上tabindex="0"则可以让元素按照文档顺序聚焦,但它不允许我们通过 Enter / Return
键来激活它们。 要做到这一点,我们必须添加下面的 JS 小绝招(JavaScript trickery):
document.onkeydown = function(e) {if(e.keyCode === 13) { // The Enter/Return keydocument.activeElement.onclick(e);}
};
tabindex扩展:
(1)当tabindex=0时,该元素可以用tab键获取焦点,且访问的顺序是按照元素在文档中的顺序来focus,即使采用了浮动改变了页面中显示的顺序,依然是按照html文档中的顺序来定位。
(2)当tabindex=-1时,该元素用tab键获取不到焦点,但是可以通过js获取,这样就便于我们通过js设置上下左右键的响应事件来focus,在widget内部可以用到。
(3)当tabindex>=1时,该元素可以用tab键获取焦点,而且优先级大于tabindex=0;不过在tabindex>=1时,数字越小,越先定位到。
兼容: 在IE中,tabindex范围在1到32767之间(包括32767),在FF, Chrome无限制,不过一旦超出32768,顺序跟tabindex=0时一样。这个估计跟各个浏览器对int型的解析有关。
2.3.2 表格
表头使用
元素定义,可以使用 <th>
scope
属性指定它们是行还是列的标题。
元素和 <caption>
<table>
summary
属性类似,都可被屏幕阅读器阅读,根据需求合理选用,不需要同时使用。
<table border="1" summary="Monthly savings for the Flintstones family"><!-- <caption>Monthly savings for the Flintstones family</caption> --><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td><td>$100</td></tr><tr><td>February</td><td>$80</td></tr>
</table>
2.3.3 图片
在使用 img
时,建议加入 alt
属性,如果是装饰的图片,可以用css背景图实现,万一要用图片,alt可以设置为空。
<!-- 装饰图片 用css背景图 或者img alt="" -->
<img src="dinosaur.png" alt=""><img src="dinosaur.png"alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth."><img src="dinosaur.png"alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth."title="The Mozilla red dinosaur"><!--下面的写法,将图像的描述作为常规文本段落给出,并给出它的“id”,然后使用 “aria-labelledby” 属性并链接到对应“id”,它使屏幕阅读器将该段落用作该图像的替代文本/标签。 如果您想将相同的文本用作多个图像的标签,这是特别有用的 - 这是使用“alt”不可能实现的。 -->
<img src="dinosaur.png" aria-labelledby="dino-label"><p id="dino-label">The Mozilla red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</p>
2.3.4 表单
在使用表单输入框时,不建议这样写:
<form>用户名 <input type="text" name="username">
</form>
如果这样写的话,屏幕阅读器只知道这是一个输入框,但不知道需要输入什么内容,所以需要一个 label
标签 来关联,最好在加一个 placeholder
属性。如下:
<form><label for="username">用户名</label><input type="text" name="username" id="username" placeholder="请输入注册时填写的用户名">
</form>
label
的 for
属性就是 input
的 id
。
当 input
获取焦点时,屏幕阅读器就能朗读 label
的内容。
对于单选框和复选框也需要使用 label
关联,如下:
<input type="radio" name="gender" id="male">
<label for="male">男</label>
<input type="radio" name="gender" id="Female">
<label for="Female">女</label>
不建议使用其它标签来模拟单选框和复选框,其它标签屏幕阅读器无法朗读选中状态。
2.3.5 链接
使用有意义的文本链接,不要使用“点击这里”这样的链接文本。使用title属性添加支持信息。
<p>我创建了一个指向
<a href="https://www.mozilla.org/zh-CN/"title="了解 Mozilla 使命以及如何参与贡献的最佳站点。">Mozilla 主页</a>
的超链接。
</p><!-- 不好的链接文本 -->
<p><a href="https://firefox.com/">点击这里
</a>下载Firefox</p>
<!-- 好的链接文本 -->
<p><a href="https://firefox.com/">下载Firefox
</a></p>
2.4 WAI-ARIA
WAI-ARIA 是W3C编写的规范,定义了一组可用于其他元素的HTML 特性,用于提供额外的语义化以及改善缺乏的可访问性。以下是规范中三个主要的特性:
- 角色 — 这定义了元素是干什么的。许多「标志性的角色」,其实重复了HTML5 的结构元素的语义价值。例如
role="navigation"
(<nav>
) 或者role="complementary"
(<aside>
),这也有一些描述其他页面结构的(角色), 例如role="banner"
,role="search"
,role="tabgroup"
,role="tab"
等等。我们通常能从UI 层面找到它们。- 属性 — 我们能通过定义一些属性给元素,让他们具备更多的语义。例如:
aria-required="true"
意味着元素在表单上是必填的。 然而aria-labelledby="label"
允许你在元素上设置一个ID,用于labelledby
引用作为屏幕阅读器指定的label 内容 ,多个也可以。当然,下面这个代码是不行的:<label for="input">
。举个例子:你可以用aria-labelledby
指定包含在a 标签中的key 描述<div>
是多个 table 表格的label ,或者将它指定为 img 标签的alt 内容 — 而无需重复在每一个img 里头定义- 状态 —用于表达元素当前的条件的特殊属性,例如
aria-disabled="true"
,屏幕阅读器就会这个表单禁止输入。状态和属性的差异之处就是:属性在应用的生命周期中不会改变,而状态可以,通常我们用编程的方法改变它,例如Javascript。
重要的一点关于 WAI-ARIA 属性是它不会对 web 页面有任何影响,除了让更多的信息从浏览器暴露给 accessibility APIs (无障碍API),这也是屏幕阅读器一类的软件的信息源。WAI-ARIA 不会影响网页的结构,以及DOM 等等,尽管这些属性可用于作为css 选择器。
何时你应使用 WAI-ARIA?
我们过去讨论了一些促使WAI-ARIA 诞生的问题。但基本上是以下四个主要领域:
- 路标/地标(Signposts/Landmarks): ARIA 的
角色
属性值可以作为地标来复制HTML5 元素的语义化(例如 nav tag)。或者超越HTML5 的语义,给不同的功能块提供「路标」,例如search
,tabgroup
,tab
,listbox
等等 。 - 动态的内容更新: 屏幕阅读器往往难以报告一直变化的内容,用无障碍特性我们能使用
aria-live
来通知屏幕阅读器某一部分的内容更新了。例如XMLHttpRequest 或者 DOM APIs。 - 优化键盘的无障碍操作: 默认的HTML 元素是具有自带的键盘辅助功能的。当其他元素与JavaScript一起进行交互时,键盘的辅助功能和屏幕阅读器的报告会因此收到影响(例如你将会难以用tab 到达理想的位置)。这是无法避免的,WAI-ARIA 提供了提供了一种允许其他元素获得焦点的方法 (使用
tabindex
)。 - 非语义控件的可访问性: 当一系列嵌套的
<div>
与CSS / JavaScript一起用于创建复杂的UI功能,或者通过JavaScript大大地增强或者更改原生的控件,可访问性将会变得极其困难——屏幕阅读器将会难以找到语义内容线索。在这种情况下,AIRA 可以帮助提供缺少了的功能,例如button
,listbox
,或者tabgroup
,另外和aria-required 或aria-posinset 这样的属性可以提供有关功能的更多线索。
注意:你只在需要的情况下使用无障碍特性!理想的情况下,你只要用原生的HTML 来实现屏幕阅读器所需的语义化内容即可。有些时候这是不可能的,一来是你对于代码的整体的控制是有限的,另一方面是总会有复杂到原生HTML 无法支持的功能需要你实现。在这个场景下,WAI-ARIA 将会变成有价值的可访问优化功能。
但还是要重申:当你需要的时候再使用无障碍特性!
aria roles和属性相关介绍可以自行前往以下链接查看
https://www.cnblogs.com/jeacy/p/6681797.html
https://www.w3.org/TR/WCAG21/#non-text-content
https://www.w3.org/TR/wai-aria-1.1/#role_definitions
3、css无障碍
- 选择合理的字体大小、行高、字母间距等,使文本具有逻辑性、清晰性和阅读舒适性。
- 确保标题从正文文本中脱颖而出,通常像默认样式一样大而粗壮。您的列表应类似于列表。
- 文本颜色应与背景颜色形成良好对比。
强调的文本: 用em/strong标签强调文本,加上简单的颜色加深即可
缩写: abbr。缩写的公认样式约定是虚线下划线,偏离这一原则明显是不明智的
<p>Web content is marked up using <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
链接: hover active link visited的状态区分开。
表格:标题醒目(通常使用粗体),并使用斑马条带化使不同的行更易于解析。
4、js无障碍
1、尽量不要用js生成大量页面内容(html,css等)
2、使用独立于设备的事件处理程序
设备独立事件包括: onfocus, onblur, onselect, onchange, onclick(click事件比较特殊,只有a以及表单、button元素foucus的时候enter键会触发,普通元素增加tabindex,用键盘操作并不会触发);设备独立事件用鼠标、键盘等都可以触发。
其它事件为非事件独立函数,比如onmouseover, onmouseout, and ondblclick,
onkeydown, onkeyup只监测键盘事件。
3、内容更新,使用复杂的widget和组件
测试
为了了解有严重视力障碍的人是如何浏览网页的,我们需要测试屏幕阅读器。有几款屏幕阅读器:
- 有些是付费产品,比如JAWS (Windows) 和Window Eyes (Windows).
- 有些是免费产品,比如NVDA (Windows), ChromeVox (Chrome, Windows, and Mac OS X), 和Orca (Linux).
- 有些内置在操作系统中,比如VoiceOver (Mac OS X and iOS), ChromeVox (on Chromebooks), 和TalkBack (Android). mac用快捷键Alt+cmd+F5 开启关闭旁白
通常,屏幕阅读器是独立运行的应用程序,并且不仅仅支持阅读网页,也支持阅读其他应用程序。也有例外(比如ChromeVox是一个浏览器扩展程序)。不同的屏幕阅读器可能在控制键和表现上稍有不同,所以你必须查阅你选择的屏幕阅读器的文档来获取相关细节。总体来说他们是大同小异的。
参考文章:
https://developer.mozilla.org/zh-CN/docs/Learn/Accessibility/HTML
https://www.misterma.com/archives/264/
https://www.w3cplus.com/html5/accessibility-tabindex.html
https://webaim.org/techniques/javascript/eventhandlers