企鹅阅读无障碍访问优化实践

avatar
前端工程师 @上海阅文信息技术有限公司

背景

2020 年末,工信部印发《互联网应用适老化无障碍改造专项行动方案》通知,并把适老化及无障碍改造水平评测和企业信用评价纳为重点工作,在国家的大力倡导下,我们更应该要关注互联网应用的无障碍访问。

全国现有 8500 多万残障人士,2 亿多 60 岁以上的老年人,还有隐藏在人群中的大量有障碍人士。我们的企鹅读书拥有着大量的用户群体,我们要提高用户的无障碍体验,让他们也能共享便捷操作,就必须要加大互联网无障碍访问在我们产品中的应用。公平无差别的对待每一位用户,增强信息获取无障碍应该成为我们产品的一部分,这也会使得我们产品变得更加人性化。

使用无障碍访问的人并不完全都是残障人士,有可能是所处环境不方便比如说手受伤了,眼镜丢了,弱视,或者在光线很强的场景下等等情境限制下,也有可能是用户的硬件出现了故障,比如鼠标坏了,等等。这时候可以借助无障碍方式访问,方便用户快捷的使用。

前言

企鹅读书是一款小说阅读程序,里面有海量书籍,涵盖原创小说、影视、品类丰富。入口:QQ=>动态=>阅读,下图为企鹅读书的首页展示。

image (1).png

现在企鹅读书无障碍的状态

借用浏览器的 Lighthouse 评估无障碍访问的平均分保持在90多。

image (2).png

当项目的评分上去了,接下来我们从移动端和浏览器端分别体验一下我们应用无障碍访问后的产品。体验一下实际场景,看看能否达到我们的预期。

移动端

如果用户开启了屏幕阅读器或者读屏软件,那么企鹅读书的页面会是什么场景呢?

以小米手机为例开启屏幕阅读器,设置=>更多设置=>无障碍=>TalkBack。

5481637202509_.pic.jpg

借用 TalkBack 来去读屏幕的内容,如视频所示:

imgservices-1252317822.file.myqcloud.com/file/121420…

在开启屏幕阅读器或者读屏软件访问的时候:

1.可以在用户选中的地方进行语言播放,它会告诉用户现在点中的是什么,可以有哪些操作。实现了很方便的通过信息化手段弥补身体机能、所处环境等存在的差异,使任何人(无论是健全人还是残疾人,无论是年轻人还是老年人)都能平等、方便、安全地获取、交互、使用信息,实现了信息传递无障碍。

2.用户每次点击按下去都会有点击反馈,足够大且规则。

3.点击区域足够大,很少会出现点不中的情况。

浏览器端

首先需要开启浏览器的无障碍访问,以谷歌浏览器为例:谷歌浏览器=>设置=>高级=>无障碍=>开启短暂突出显示焦点对象/使用文本光标浏览网页 

当开启设置之后,可以发现所有可以聚焦的地方都有一个很明显的聚焦状态如图所示

企业微信截图_465312c0-6a56-46f4-9a40-edf36529f20c.png

再来假设一个场景,鼠标和触控板坏了,我们只有键盘,在这种情况下,是否还能正常的访问页面,经过操作发现我们可以借助键盘的 tab 进行页面大多数的操作,几乎没有被影响,如视频所示

可能有朋友会好奇,这是如何实现的?欲知后事,请继续阅读下面内容

企鹅读书做了什么

之所以会达到对用户操作如此友好的效果,是因为我们团队对项目进行无障碍改造,主要包括以下方面:

1.DOM 语义化

使用正确的 HTML 是无障碍 web 内容保证,在我们借助无障碍设备访问的时候,能够正确告诉用户你当前正在做什么,比如连接跳转用 a 元素或者 role='link',选中这个元素之后按下回车键,页面会发生跳转;

当我们借助 TalkBack访问的时候,会告诉用户这个a标签的内容并且可以点击跳转,像视频中这样

imgservices-1252317822.file.myqcloud.com/file/121420…

我们需要注意的是,在页面中会出现一些装饰性的图片,此时并不能使用 img,因为一旦使用了影响语义化,会误导用户因此会建议使用i或者伪元素实现。

div+span 一把梭,并不是一个很好选择,它会导致页面结构混乱,同时也直接影响了无障碍访问,因此我们要让正确的标签做正确的事(figure,img,figcaption,section,button....),让它们各司其职,发挥最大的作用。

2. WAI-ARIA实现辅助识别

有时候,我们会需要非语义HTML 和动态的 JavaScript 内容更新的复杂UI控件,这时候使用语义化标签可能很困难。此时我们就需要一些辅助技术来帮助我们进一步地识别以及实现语义化,既能帮助我们解决问题,也让用户可以了解发生了什么。

比方说下图绿框框圈中的点点点按钮,点击这个按钮是唤起“更多操作”弹窗,这是一个图形按钮,想必很多前端开发会以 button > svg 的结构实现。

image (3).png

对于普通用户,上面的实现是没有任何问题的,但是对于屏幕阅读这类辅助设备,上面的实现是困惑的,因为会阅读“按钮 -> 图像”,实际上,图像是干扰信息,按钮则缺少明确的描述。

此时可以使用 aria-* 这类无障碍访问辅助属性进行优化,实现如下:

  • 在 上面添加 aria-label="更多操作",增加对按钮的描述;
  • 在 上面添加 aria-hidden="true",避免对无用图像信息的阅读; 此时,当我们借助TalkBack或者阅读屏幕软件访问的时候,它就会语音播报“按钮 -> 更多操作”,这时候用户就知道,这个按钮是有什么用了。

如视频所示

imgservices-1252317822.file.myqcloud.com/file/121420…

这就是借助WAI-ARIA basics辅助技术解决问题的一种方案,或者在有些情况下因为某些原因,我们连接不能使用a标签,只能使用div,这时候我们同样可以使用辅助技术帮我们解决问题,在div标签上面写上role="link" 就好了

image (4).png

为了提高无障碍访问,辅助技术在企鹅读书项目中使用频率很高,比如role="link" tabindex="0",aria-label='点击切换作品' role="navigation" role="tab" role="tablist" role="tabpanel"以及aria-selected="true" 和 aria-selected="false" 的识别。

这些都是提高无障碍访问的一种实现方式。

3. 点击反馈和点击区域扩大

上面的无障碍访问处理更多的是面向非常规交互场景和特殊用户群体,而这里的 无障碍访问处理则是面向普通的用户,并且是广大前端开发者普遍忽略的问题。

  • 点击反馈 大家如果注意过 iOS 或 Android 等操作系统,会发现,其所有的操作在按下的时候都会有反馈,这个反馈可能是颜色的变化,可能是尺寸的变化,也可能是声音或震动,总之,只要是可交互的操作,在按下的时候一定会有反馈。

又比如用户体验做的很好的一些 App,例如微信,用户在操作的时候也是会对应的反馈的。但是市面上也有不少 App,在这一块是忽略的,也就是按钮按下是没有任何反应的,这个其实是不符合基本的交互规范的。

企鹅读书在这一块做了非常好的支持。所有的按钮、所有的链接全部增加了反馈态。

全局代码如下所示:

a[href]:active,
button:active,
label:active,
[role="button"]:active,
[role="link"]:active {
  background-image: linear-gradient(rgba(0, 0, 0, .05), rgba(0, 0, 0, .05));
}

image (5).png

image (6).png

image (7).png

从上面的 CSS 代码可以看出,我们的交互反馈态是和 HTML 语义走的,这样,让无障碍访问和交互效果保持了一致性。

上面的这段 CSS 代码可以覆盖整个网站 90% 以上的点击反馈态交互效果,其它无法覆盖的场景会专门处理,主要是两类:

一个是黑色按钮,因为基本的点击反馈交互是背景色加深,所以黑色按钮点击的时候是没有视觉变化的,此时我们改为颜色减淡:

image (8).png

.button-black:active {
    background-image: linear-gradient(hsla(0, 0%, 100%, .15), hsla(0, 0%, 100%, .15));
}

另外一个是纯图像点击反馈,此时使用滤镜降低图像的亮度实现:

屏幕录制2021-12-14 下午1 (3).gif

img:active {
    filter: brightness(0.9);
}
  • 点击区域 优雅扩大按钮或列表的点击区域,既是一项细致活,也是一项技术活,因为,点击区域的扩大往往对布局能力的要求更高。

例如下图,列表是左右各有 1rem 间隙的,如果不考虑尽可能扩大列表的点击区域,开发人员往往会外部容器设置好左右间隙,列表内容自然排列这样实现。

img-1.png

这样实现虽然视觉也没问题,但是点击的时候,左右 1rem 就不是可交互区域,所以实现的时候,列表需要贯穿整个页面,这就对“第一反应”下的布局方案造成了挑战。

列表的例子其实还好,开发人员往往不注意的是一些看起来不起眼的点击按钮。

比方说搜索这里的“清空”按钮,是小图标+文字的形式,如果开发人员缺少相关的意识,最终点击区域的大小就会和按钮所在的行高一样大,如下图所示:

image (10).png

18 像素高度的按钮在平静状态下是比较容易点中的,但是在走路,或者摇晃的公交车,或者手上提着其它东西的场合,往往并不能一次性就点中,而带来用户体验的问题。

这样的问题致命么?不致命,并且测试同事绝对测不出来,但是,它会让产品的操作体验变得不流畅,潜移默化中降低对对产品的好感,在不经意间造成用户的流失。

我们可以稍加处理,例如,添加一段 padding 声明,同时微调下布局位置,就能在既保证视觉还原的情况下,也保证上佳的用户体验。

button {
    padding: .5rem;
}

image (11).png

类似的例子还有很多,就不一一举例了,总之,在企鹅读书中,只要是按钮,一定是保证足够的点击区域大小的,让用户在操作过程中,流畅。

4. 关闭没有必要的动画

这是很多产品都会忽略的用户体验问题。

对于部分用户,那种闪烁的动画可能会诱发癫痫,普通人觉得很自然流畅的过渡动画,会诱发类似晕车的反应,以及部分用户为了让手机电量更持久,或者低耗电模式下,都会关闭系统的动画。

这是所有操作系统都具有的选项,属于基础的用户无障碍访问知识,在各个系统下关闭动画路径如下:

  • 在 Windows 10 中:设置 > 轻松获取 > 显示 > 在 Windows 中显示动画。

image (1).png

  • 在 Windows 7 中:控制面板 > 轻松获取中心 > 使计算机更易于查看 > 关闭所有不必要的动画(如果可能)。
  • 在 MacOS 中:系统偏好 > 辅助功能 > 显示 > 渐弱动态效果。

image (2).png

  • 在 iOS 上:设置 > 通用 > 辅助功能 > 减弱动态效果。 image (3).png

  • 在 Android 上:设置 > 辅助性(或无障碍) > 移除动画(或关闭高级视觉效果,这个视手机品牌不同会有区别。 可惜,几乎很少有 Web 产品会跟进系统的设置,而进行相应的用户体验处理,企鹅读书在这块就做的不错。

对全站的 transition 过渡和 animation 动画都进行了处理(不包括loading和pull 下拉),如果同步关闭了系统动画,企鹅读书这块会同步关闭动画,例如下面的录屏 GIF 示意:

屏幕录制2021-12-14 下午1 (2).gif

实现其实很简单,浏览器提供的对应的媒体查询,CSS 代码示意(reduce可以省略):

@media (prefers-reduced-motion: reduce){
  .popup {
    transition: none;
  }
  .overlay {
    animation: none;
  }
}

当然,为了不和主业务冲突,方便日后的维护,可以可以专门拎一个 CSS 文件做这样的事情,例如:

<link rel="stylesheet" href="reduced-motion.css" media="prefers-reduced-motion">

未来发展

做无障碍访问是一件非常有意义的事情,无论是人文关怀的角度,还是对产品的收益方面。因为即使手脚健全,视力健全的用户也会存在有障碍访问的场景。

万事开头难,刚刚开始写无障碍的访问,会有些不知所措,不知从何下手。

好在如今项目一期已经做完了,在一期项目中里面基本包含了大部分常见的无障碍访问处理场景。

我们会在在后续的项目迭代中,把无障碍访问成为项目需求的一个基本要求,保证项目后期的可持续发展。预先制定好规范,在大家达成共识之后,遵循规范下进行无障碍访问的开发,其实并不会带来更高的一个人力成本,却可以给用户提供更好的体验,体现我们的社会责任感。

项目无障碍访问的改造和可持续发展,路长而道远,非一早一夕就能做好的。

除了规则制度的要求之外,更多的是需要我们发自内心的要去做这件事,并且做好它。

参考文档

基于VoiceOver的移动web站无障碍访问实战

WAI-ARIA无障碍网页应用属性完全展示

HTML tabindex属性与web网页键盘无障碍访问