WAI
无障碍设计无障碍设计是指产品, 设备, 服务, 或者环境是为残疾人士设计的。无障碍设计的概念意味着与一个人的辅助技术(例如, 电脑屏幕阅读器)相兼容, 确保直接访问(即独立)和"间接访问"。 无障碍设计可以理解为 "能够访问", 并对一个系统或实体是有利的, 其侧重于使身体残障, 或有特殊需要, 或要依赖辅助技术的人群能够访问 Web。然后, 研究和开发无障碍设计对每个人都带来了好处。 无障碍设计不应该和可用性混淆。 大多数情况下, 可用性是指产品(如: 设备, 服务, 或者环境)能在特定的环境下被特定的用户使用, 来高效地实现制定目标。 无障碍设计和通用性设计是息息相关的。通用型设计是指产品的创造过程中, 产品对人们是可用的, 并尽可能最大范围覆盖各能力范围内的人群和各种情形下的操作, 即对所有人是可访问的(无论他们访问 Web 是否有障碍)。 富互联网应用开发人员使用HTML、CSS和JavaScript创建富互联网应用程序时,往往把残疾人士抛在脑后,因为这些应用程序无法提供被辅助技术理解所需的语义信息。可悲的是,直到现在这种情况并没有多少改变,其实我们可以扭转这种局面。WAI-ARIA能够提供足够的语义,以确保富互联网应用是可以理解的,并且现在已经得到相对较好的支持。 ARIA是什么?ARIA是“**Accessible Rich Internet Applications **”的缩写。它是W3C的 Web无障碍推进组织(Web Accessibility Initiative / WAI) 在2014年3月20日发布的 可访问富互联网应用 实现指南。 WAI-ARIA是一个为残疾人士等提供无障碍访问动态、可交互Web内容的技术规范。在 WAI-ARIA概述 中对WAI-ARIA及其他支持文档进行了介绍。 简单点描述:
如何使用ARIA?应用于HTML的ARIA有两部分组成: **role** (角色)和带 **aria-** 前缀的属性,其作用:
HTML中的ARIAARIA在HTML中使用有其自己的规范,并不是说在HTML中使用了ARIA,Web页面就无障碍化了,就提高了可访问性了。言外之意,ARIA没有用好,反而会把你带到另一个坑中,使用你的页面可访问性更差。 有关于HTML中ARIA的文档可以 点击这里阅读 。 ARIA在HTML中的使用ARIA使用规则一如果你使用的元素( HTML5 )具有语义化,应该使用这些元素,而不应该重新定义一个添加ARIA的角色、状态或属性的元素。 那么什么时候可用和不可用ARIA呢?
ARIA使用规则二不改变语义,除非你真的需要使用。例如,开发者想创建一个标题,而且它是一个按钮。 不要这样做:
建议这样做: 或者说,你不使用正确的元素,但你可以这样做:
如果使用一个非交互的元素做为一个交互的元素,那么开发人员必须使用ARIA添加语义和使用适当的脚本增加交互行为。ARIA使用规则三所有的ARIA制作控件都必须具有键盘(keyboard)事件。 如果创建一个组件(widget),用户可以点击、拖放、滑动或滚动,用户使用键盘能定位到创建好的组件部件上,并且执行相应的操作动作。 例如,如果使用 role=button 必须能够接收到焦点和用户能够使用键盘激活相应动作,比如Win操作系统上的 enter 和iOS系统上的 return 或者键盘的空格键( space )。 ARIA使用规则四不建议在可获取焦点元素( focusable )使用ARIA的角色: role=presentation 或 aria-hidden="true" 。 可获取焦点元素上使用ARIA这两规则,会导致一些用户无法获取元素焦点。 不要这样做: 也不要这样做: 如果说一个交互元素无法看到或者不能与之交互,那么可以尝试使用 aria-hidden ,例如: button {visibility:hidden} 如果一个交互元素使用 display:none; 来隐藏,那么它对应的 可访问性 也将一并被删除,如此一来,在可交互元素上使用 aria-hidden="true" 就没有必要了。ARIA使用规则五所有交互元素都必须有一个 可访问的名称 。 当可交互元素的可访问性API的可访问名属性只有一个值时,那么可交互元素就只有一个可访问的名称。 比如下面的示例, input type="text" 有一个可见的 user name 或者: 此时MSAA( Microsoft Active Accessibility )控制器的 accName 属性是空的:
相比之下,下面示例中 input type="text" 有一个可见的 或者: 此时MSAA( Microsoft Active Accessibility )控制器的 accName 属性值是 user name :
另外 label 标签元素是不能被用来给自定义控件提供一个访问性名称,除非 label 引用了HTML的 labelable 元素 。 MSAA( Microsoft Active Accessibility )控制器的 accName 属性值是 user name :
除此之外,使用非HTML labelable 元素来模拟控件,不管给其分配什么角色( role )都不会是HTML的 labelable 元素,比如下面的 div 元素: MSAA( Microsoft Active Accessibility )控制器的 accName 属性值是空的:
ARIA 的角色 role下面的表格详细的示意了HTML中元素如何使用ARIA的角色 role ,以及对应的含意:
上表中并没有列出所有ARIA的角色,当然并不是所有的HTML元素都具有对应的ARIA的 role ,下表列出了常用的标签元素对应的ARIA的 role ,仅供参考:
注释一通过一个示例来看看 role="presentation" 运用前后对HTML元素可访问树对比。
在上面的代码上添加 role="presentation" :
table 元素可访问树前后对比示意图如下:
前面也说到过,并不是在HTML中添加ARIA角色对屏幕阅读器就是好的,特别是对于一些默认带有交互功能的元素中,添加ARIA就是浪费时间,比如:
当然在HTML5的一些特定元素上,ARIA的 role 和自带的语义化元素是可以重叠的,如下表所示:
假设有一个简单的HTML5页<面: 如果你不想使用HTML5的元素,可以使用 div 来替代: 如图所示:
ARIA的属性下表介绍了ARIA相关属性的使用方法。
ARAI状态下表介绍了ARIA相关状态的使用方法。
有关于Roles、States 和 Properties相关规范文档(W3C规范)
开发最佳实践开发一个可访问的 Web 应用不仅需要工具的支持,浏览器的支持,还需要开发人员遵循一定的规范提供对应的元素信息,才能达到最终的目的。下面着重介绍一些开发中的最佳实践。 关于 Image图片或者动画均需提供 alt 信息,使得读屏软件可以将图片动画的内容清楚的读出来。如图所示:
对应的 HTML 如下: 对于某些用于装饰性的图片,则需设置 alt 为空,使得读屏软件可以忽略此元素。如图用于装饰页头的图片,实际并没有传递有价值的信息。
对应的 HTML 如下: 必须设置一个空 alt 属性的目的是为了能通过 Webking 的检查,并且使得读屏软件能够忽略此元素。 对于图表文件, alt 属性的设置则需要简明扼要的表达出图表的信息,并不用把里面的细节都详细得描述出来。例如下面的图 alt 信息设置为销售额从 1996 年到 2004 年间持续稳定增长,从 400 万增长到了 1600 万。并不需要把每一年的增长额都详细得描述出来。
对于放在链接里面的图片,如果已经有文字的说明, alt 也设置为空,这样避免读屏软件重复同样的内容。如下面的 HTML:
a 的内容已经指明了这是个苹果手机, img 的 alt 属性就没必要再设置一次了。否则读屏软件会连续读两次重复的内容,引起混乱。 CSS 将样式跟结构分离,使得 HTML 代码结构清晰。很多装饰性的图片也都放在 CSS 里面来加载,带来的一个问题就是在 CSS 里面的图片在高对比度模式下都无法显示。如果这个图片并不仅仅是装饰性的,还可以触发功能,那就需要从 CSS 里面拿出来,当成一个独立的 img 或者 input 元素。例如下面的一个提示保存的图片
写在 CSS 里面的做法是: .save_button{ background: url("images/save_button.png"); width: 33px; height: 33px; vertical-align:middle; } 这样当用户切换到高对比度模式,这个图片就是一片空白,用户无法再去点击保存。修改如下: 在一个图片列表里面选中某个图片,区别选中去否我们通常的做法是用边框的颜色来标识。如下图,选中的图片边框为蓝色
.selectedIcon{ border:5px solid #ACC6F3; } .unSelectedIcon{ border:5px solid #C0D4F7; } 但这样的一个实现实际上违反了可访问检查列表中的一项:不能仅仅通过颜色来区分不同的元素,因为在高对比度下只有黑色或白色,这样的区分在高对比度下是没有任何作用的。我们很容易想到的一种办法就是只有选中的时候才加边框,未选中时则没有边框,这样就可以区分出来了。修改如下: .selectedIcon{ border:5px solid #ACC6F3; } .unSelectedIcon{ border:0 none; } 这样引起的问题是,图片的布局在选中的时候会浮动,增加了 5px 的边框,看起来效果就很差。那么怎么保证布局又满足可访问性的要求呢? 可以在上面 CSS 的基础上通过 padding 属性使得布局正确: .selectedIcon { border:1px solid #ACC6F3; padding:4px;} .unSelectedIcon { border:0 none; padding:5px;} 这样保证整体的边界都是 5px ,在高对比度下的效果如图所示:
关于 TableTable 分为两类:一类是做布局的 table ,一类是数据 table 。对于布局用的 table ,读屏软件没必要知道这是一个表,可以通过设置 role=presentation 使 JAWS 忽略这个表,只关注里面的内容。对于数据表格,则需要设置 caption 属性,说明整个表是用来做什么的,使得 JAWS 可以告诉用户这个表的作用。对于每一个单元内的数据,还应该通过 th 属性使得 JAWS 能识别这个数据的表头是什么。对于复杂表,可以通过 id 和 header 属性来标识。如图所示 :
以第一行的数字 5 为例,正常人可以很容易得看出 5 指的是一年级 Mr.Henry 老师这个班的男生有 5 个,但当 JAWS 面对这个数字 5 的时候,怎么能识别出来呢?通过 header 来标识表头, header 的值就指向对应表头的 id 。对应的 HTML 如下:
关于 Formform 元素需要关联一个 label 元素,所有的 button 都已经有了一个隐含的 label ,所以不再需要显示关联。对于 input , select , checkbox , radio , button 则都需要显示一个 label 元素。这样 JAWS 在面对这个表单元素的时候才能告诉用户这个表单的作用。例如下面的 input , JAWS 会告诉用户这个是需要输入名字的一个输入框。当 label 属性不方便使用的时候,还可以通过 title 属性达到相同的效果,也可以满足 Webking 检查的需要。下面的两种写法都可以。但前提是 name 不需要被显示出来。当 title 和 label 都设置的时候 title 会被 JAWS 忽略。 或 当一个表单元素如果前后都需要描述的时候, label 就显得力不从心了。ARIA 规范的出现解决了这一问题。 aria-labelledby 属性可以设置多个值,说明这个表单元素是被那些值所描述的, aria-describedby 属性则更详细的扩展了这个描述。如下图所示:
当 JAWS 把焦点放在 10 上的时候,会告诉用户 10 表示的是 10 分钟刷新一次。对应的 HTML 代码如下所示。 aria-required 的属性标识这个元素是必须的,JAWS 识别此元素并告知用户必须输入此元素。我们可以看到中间的 input 元素被多个元素来描述( aria-labelledby 中的几个 id 值),这样 JAWS 就能够识别这个标签,并且按照这个标签的顺序读出前后的 label , 并且提示用户如果还有更详细的描述以及如何获取这个更详细的描述。当用户需要时, aria-describedby 所对应的元素信息就会被读出来。增强了视力有障碍人士与普通人了解内容的一致性。 minutes Allows you to specify the number of minutes of refresh time. 关于 Tabindex 与获取焦点的顺序Tabindex 属性的使用可以使得原本无法取得焦点的元素获取焦点。目的是为了使用户可以用键盘访问任何可以用鼠标访问的元素。我们知道,使用 Tab 键可以按文档顺序 tab 到所有可以获取焦点的元素。 tabindex 可以设置为 -1 , 0 或者是任何自然数。
当用户使用 Tab 键浏览页面时,元素获取焦点的顺序是按照 HTML 代码里面元素出现的顺序排列的,有时跟实际看到的页面顺序并不一致。例如图 所示的页面:
按照页面顺序,tab 的顺序为自左向右,可实际上操作的时候却发现“search all”出现在了“go to edit”的前面。对应的 HTML 代码如下所示: welcome page search all go to edit 原来是通过 float:right 达到了布局上的效果,实际文档顺序确实是 search all 在前面的。所以为了不引起混淆,最后能保持代码的顺序与实际呈现出来的页面上的顺序一致。可以修改上面的代码为,如下所示: welcome page go to edit search all 关于隐藏的内容隐藏的内容分为两种,一种是为了布局的需要,在条件满足的情况下才会显示出来;另一种是只给读屏软件读的内容:有时候我们为了使读屏软件更准确的读取信息,会提供一些额外的描述来达到此效果,但为了不给正常用户带来困扰,这些内容对正常用户来说是隐藏起来的。隐藏内容我们通常用 display:none 或者 visibility:hidden 来表示,但读屏软件同样也会忽略这类内容。那如何隐藏内容又能使读屏软件读出来呢?另外一种隐藏内容的方式是使用绝对定位使得内容不出现在当前屏幕上,如: {position:absolute;top:-30000px;} 所以在选择使用哪种方式隐藏内容时就需要慎重考虑, display:none visibility:hidden 对任何人都是隐藏的,如果想只给读屏软件读到就需要使用上面的绝对定位方式。例如在下图所示的菜单的选中项上加上如下的 css: is selected .access{ position:absolute; top:-30000px;}
这样当用户使用 JAWS 浏览每一个菜单项时,在选中项上就能听到哪一项是当前的所选中。 高对比度模式的小技巧系统切换到高对比度模式,只有黑白两色,很多在正常模式下依靠颜色来区分的(如界面边界)都无法辨识了,写在 CSS 里面的很多图片也都无法显示出来。此时就需要在高对比度下增加边界或者另外 DOM 节点来显示同样的内容。Dojo 的 WAIState Api 提供了一种方式来判断系统是否处于高对比模式,如果是则在 body 上增加 dijit_a11y 的一个 CSS。这样可以在正常模式下显示一个 DOM 节点在高对比度下显示另外一个 DOM 节点,从而方便的区分。如下图所展示的正常模式与高对比模式下的对比:
正常模式下如左图所示,子菜单通过一个图片标识,但这个图片是在 CSS 里面设置的,切换到高对比度模式即无法显示出来。此时,我们增加一个在高对比度模式下才显示出来的节点,达到如图右所示的效果,在高对比度下显示一个 + 号。代码如下所示,在高对比模式下, dijit_a11y 加在 body 上,dijitMenuExpandA11y 所对应的 DOM 即应用右面的 CSS 得以显示出来。
ARIA WidgetsLabelARIA前
Personal Folders
ARIA后
Personal Folders
Alert DialogConfirm Close headings
list/listitem... ... ... buttonButton? toggle buttonOptionOption checkboxOptionOption radioYesNoMaybe linklink tooltip...... this is the tooltip text status barsome form of status bar message... alertan alert message (no user interaction) progress barmenuMenubarlistboxOption 1 Option 2 Option 3 comboboxOption 1 Option 2 Option 3 tree... ... ... ... ... grid... ... ... ... Bootstrap ARIA示例GlyphiconsDropdownsDividerButton GroupsButton dropdownsInput groups@ @example.com PaginationAlertWarning! Better check yourself, you're not looking too good. Progress bars60%< |