本文参考 WCAG 2.1 、WAI-ARIA 和 Web 可访问性与无障碍最佳实践,在京喜小程序首页无障碍优化开发中,总结了一些“无障碍优化”在小程序端的实践,但愿以此推进无障碍在小程序更多地落地。html
在了解无障碍以前,咱们先来了解一些数据:前端
无障碍 (Accessibility),是指在发展过程当中没有阻碍,活动可以顺利进行。从无障碍引伸的相关词汇有,无障碍设施、信息无障碍、无障碍交流等等。小程序
对于信息无障碍,中国互联网协会给出了一个定义:任何人(不管是健全人仍是残疾人,不管是年轻人仍是老年人)在任何状况下都能平等地、方便地、无障碍地获取信息、利用信息。微信小程序
以上释义,源自百度百科
若是看不见、听不见,咱们该怎么生活呢?浏览器
在生活中,咱们经常会看到一些设施:缘石坡道、盲道、无障碍垂直电梯、无障碍扶手、人行横道的警示信号等等。这些给障碍群体使用的安全设施,就是无障碍设施 (Accessibility Facilities)。无障碍设施主要是为了让障碍群体可以自主、安全、方便地通行和活动,它是障碍群体生活顺畅的重要保证。除物质环境的无障碍设施,无障碍设施还能够扩展到信息和交流的无障碍,好比互联网中的网站设计、网上办事、购物交互等。安全
随着互联网不断发展,互联网应用已经融入到咱们生活的各个方面,行动不便的障碍群体则更但愿也更须要经过方便的互联网应用获取信息、学习和生活。所以,互联网应用进行无障碍优化,对障碍群体显得尤其重要。微信
早在 1997 年 2 月,万维网联盟 (W3C) 为了提高网络的无障碍性,成立了网络无障碍推进 (WAI)小组,并制定了一系列的关于网络无障碍的标准、规范、检测表、无障碍的技术,并与世界各地的组织携手合做,在全球范围推进无障碍网络运动。网络
但至今为止,互联网产品的无障碍优化进展仍然缓慢,不少网站建设和移动端 APP 的开发都还未考虑无障碍优化,即便是经过读屏软件,也很难获取想要的信息。架构
咱们以电商平台购物 APP 为调研对象,同信息无障碍研究会合做作了一个调研。根据收集到的舆情反馈,咱们了解到:app
在消费降级的当下,低价商品火遍互联网的每一个角落,障碍群体是其中需求度最大的人群之一。京喜,做为京东旗下的拼购电商平台,与拼多多和淘宝特价版同样,在障碍人士汇集的论坛和QQ中,有很是多的讨论。用户们对京喜没作无障碍表示遗憾,也期待京喜能够尽快开展无障碍优化,享受低价拼购的乐趣。
根据研究会信息无障碍工程师初步检测,目前影响障碍用户们使用缺陷集中在如下几类中:
以上几类属于障碍用户可以无障碍使用的基本支撑,部分或彻底适配后将能促使 APP 实现较好的无障碍体验。
在了解小程序的无障碍优化以前,首先须要了解 Web 无障碍开发的基础知识,及读屏软件的工做方式。
无障碍访问的关键点 —— 使用屏幕阅读器。
移动端 APP 访问无障碍特性,开启读屏模式的设置路径:
设置 -> 通用 -> 辅助功能 -> 旁白(VoiceOver)
。设置 -> 辅助功能 -> 无障碍 -> TalkBack
(不一样机型路径可能不同)如下是一些主要的 VoiceOver 手势:
安卓的 TalkBack 手势与 VoiceOver 有一些差别,后面还会提到……
WAI-ARIA
经过浏览器把信息暴露给 accessibility APIs (无障碍API),做为读屏软件的信息源。
WAI-ARIA ( Accessible Rich Internet Applications (WAI-ARIA) 1.1) 是一项技术,它能够经过浏览器和一些辅助技术来帮助咱们进一步地识别以及实现语义化,这样一来能帮助咱们解决问题,也让用户能够了解发生了什么。WAI-ARIA 是 W3C 编写的规范,定义了一组可用于其余元素的 HTML 特性,用于提供额外的语义化以及改善缺少的可访问性。
如下是规范中三个主要的特性:
role='button'
表示元素是按钮,读屏软件会读做“按钮”、role='searchbox'
表示元素用于搜索,读屏软件会读做"搜索"。aria-required='true'
表示元素在表单上是必填的、aria-label='描述文字'
用来给当前元素标签加上描述,用不可视的方式给元素加 label,接受字符串做为参数,读屏软件会将描述文字朗读出来。aria-disabled='true'
aria-hidden='true'
表示元素会被读屏软件忽略。更多属性能够参考 Using Aria 中的 States and properties,部分属性可能在小程序设置不生效。
更多 role 能够参考 Using Aria 中的 Widget Roles,部分 role 可能在小程序设置不生效。
所以,无障碍优化即可以借助读屏软件,结合 WAI-ARIA 的特性进行开发。互联网应用引入无障碍特性,使得障碍用户能够清晰准确的获取到页面信息,得到更好的产品体验,方便地实现网上办事、购物等。
此前,京喜小程序未进行无障碍优化,障碍群体在读屏软件的辅助下,基本不能使用。这使得平台失去了障碍群体的市场,同时障碍群体也失去了体验京喜小程序平台服务的机会。所以,但愿对平台进行无障碍优化,提高平台的可用性、易用性,让障碍群体享受更好的购物体验。
产品提供焦点划分规则、朗读规则、阅读顺序,为京喜小程序首页量身定制无障碍优化方案。内部方案,这里就不透露了。(想了解的话,来投一波简历啊~)
目前小程序官方已经支持无障碍访问特性,用户在读屏模式下能够体验无障碍访问。
DOM 顺序很重要
读屏软件在读屏时默认按照 DOM 的顺序朗读。
若是 DOM 的顺序与内容的语义顺序不一致,会使得内容难以理解。例如首页中的商品瀑布流,按左右两列布局:
在开发过程当中应尽可能避免使用会影响到 DOM 视觉顺序的样式,若是没法避免,须要手动设置 tabIndex 属性,告知读屏软件正确的内容顺序。
非文本元素增长描述和角色属性
经过给非文本元素增长描述和角色属性,元素的内容就能够被读屏软件清晰准确地朗读。
“描述图像内容 图像”
。aria-role
和 aria-label
属性。 读屏软件会朗读出 “label 描述内容 + role 类型”
。整块元素读取
一个元素可能由不少子元素组成。在无障碍模式下,读屏软件只能分别聚焦子元素,单独将每一个子元素信息读出来。障碍用户在读屏软件的辅助下,获取到的都是元素零零碎碎的信息,这样的体验很不友好。
所以,在无障碍优化过程当中,能够将元素看成按钮整块朗读,将子元素的信息整合做为描述,并尽可能精简描述内容,缩短朗读文案的时间。
隐藏元素读取
若是不但愿部份内容被读出来,可使用 aria-hidden='true' 来声明,这样读屏时就会忽略这些元素。
<Text aria-hidden='true'>读屏时会忽略这行文本</Text>
在无障碍模式下,这个属性可用来隐藏辅助做用不大或是具备干扰性的内容。
非文本元素读取
首页头部中京喜 Logo 和文字是一整张图片。聚焦后,读屏软件默认会读成图像,没法将图片中的文字朗读出来。这样的无障碍体验是很是差的。
在这个场景下,可经过给 Logo 图片增长描述
来进行无障碍优化。
<View className='index__main'> <View className='index__logo' aria-role='text' aria-label='京喜' /> <View className='index__title'>京东旗下社交电商平台</View> </View>
相似的还有关闭按钮、返回顶部按钮、菜单栏按钮……
<View className='back-top' aria-role='button' aria-label='返回顶部' />
搜索框读取
首页搜索框聚焦后,读屏软件默认会将搜索框中的暗纹读出来。可是障碍用户并不能明显的感知到搜索框元素。
在这个场景下,能够经过给搜索框增长角色属性
来进行无障碍优化。
<View aria-role='searchbox'> <SearchBar /> </View>
轮播图读取
轮播图由多个子元素组成,但点击为整块点击,且每一个子元素都是图片,读屏软件没法让用户清晰感知元素的含义。
在这样的场景下,能够给每个子元素标签增长描述
,读屏软件就能够识别到子元素了。
<View className='banner'> <Swiper> <SwiperItem aria-role='text' aria-label='活动推荐1'>活动1</SwiperItem> <SwiperItem aria-role='text' aria-label='活动推荐2'>活动2</SwiperItem> <SwiperItem aria-role='text' aria-label='活动推荐3'>活动3</SwiperItem> <SwiperItem aria-role='text' aria-label='活动推荐4'>活动4</SwiperItem> </Swiper> </View>
但这样的无障碍优化在安卓手机上体验并不友好。
当障碍用户聚焦到轮播图后,读屏软件将子元素的描述朗读读来。轮播图继续轮播,焦点索引却不会随轮播状态自动更新,而是跟随当前子元素滑动消失在屏幕中。若要获取更新后的轮播信息,须要从新聚焦。
在这样的场景下,建议在轮播图的最外层增长描述
,将整块内容看成按钮处理,让障碍用户清楚这是总体点击的按钮。
<View className='banner' aria-role='button' aria-label='活动推荐,共4个'> <Swiper> <SwiperItem>活动1</SwiperItem> <SwiperItem>活动2</SwiperItem> <SwiperItem>活动3</SwiperItem> <SwiperItem>活动4</SwiperItem> </Swiper> </View>
商品卡片读取
商品卡片由多个子元素组成,读屏软件会将聚焦的子元素(商品图、名字、价格、利益点等)一个个的读出来。
但单独读出每一个子元素,不便于障碍用户理解商品卡片的完整含义。
相似这样的场景,能够将商品卡片看成一个按钮整块处理。在商品卡片最外层标签加上 aria-role='button'
,还能够经过 aria-label
标签,将商品信息进行整合,精简描述,缩短商品名字的朗读时间,让障碍用户得到更好的体验。
隐藏元素读取
上文提到商品卡片的无障碍优化可经过 aria-role='button'
和 aria-label
来实现。理想状况下,当障碍用户聚焦到商品卡片,读屏软件将整合的商品信息朗读出来,并提示是按钮类型。
但实际状况并不是如此。当障碍用户在安卓手机上聚焦后,读屏软件不只会将整合的商品信息和 role 朗读出来,还会将商品卡片子元素的文本内容朗读出来。(后文会提到 iOS 的表现)
为了不商品信息重复朗读,能够在元素文本标签上加上 aria-hidden='true'
,隐藏子元素文本描述,让障碍用户可以获取到清晰简洁的商品信息。
<View aria-role='button' aria-label='商品整合信息'> <View aria-hidden='true'> <Image className='goods__img' src='/img/bVbPbr5' lazyLoad /> <View className='goods__info'>商品信息…</View> </View> </View>
滑屏手势差别
安卓:双指滑动,根据手势自适应滑动;
iOS:三指滑动,一屏一屏分页滑动。
轮播图焦点差别
安卓:焦点位置会跟随子元素滑动消失;
iOS:焦点位置固定不变,不会随子元素滑动而消失。
价格读取差别
因为整数部分和小数部分字体大小不一样,价格文本是用多个标签实现的。
<View> ¥ <Text>259</Text> <Text>.2</Text> </View>
安卓:完整朗读 “259.2元”;
iOS:单独朗读单位、整数、小数,而且会将 “¥” 读做“美圆符号”。
aria-role='button' 读取差别
安卓:读做“描述+按钮+子元素文本描述”,需借助 aria-hidden='true'
隐藏子元素文本描述,避免信息重复朗读。
iOS:有两种状况。
aria-label
,则读做“描述 按钮”,不重复朗读子元素文本。aria-role='button'
,会继续识别子元素文本,读做“描述+按钮+子元素文本描述”。为避免重复朗读,也须要给子元素加上 aria-hidden='true'
。小程序基础库自 2.7.1 起,支持部分 ARIA 标签,可是仍有部分属性和 role 在小程序中不生效,但愿将来能够支持全部的 ARIA 标签,给障碍用户带来更好的体验。
另外,小程序目前尚未相关 API 支持识别用户手机是否开启无障碍(读屏)模式(原生 APP 能够经过相关 API识别)。若是能预知用户手机开启了无障碍模式,就能够经过动态控制前端模块展现,从而更好的隐藏无用信息、排除干扰信息(浮层弹窗、动画等)。在启无障碍模式下,设置数据埋点上报,还能够为障碍用户提供更好的体验。
但愿微信小程序能尽快增强对无障碍优化开发的支持力度,让障碍群体可以享受信息化所带来的成果,享受便捷美好的生活。
手机开启读屏模式,扫码二维码体验:
京喜小程序首页无障碍优化上线后,咱们对调研的障碍群体进行了回访,而且获得了不错的体验反馈。
这是咱们在小程序无障碍优化上迈出的第一步,要得到更好的小程序无障碍访问体验还有很长一段路要走……
欢迎关注凹凸实验室博客:aotu.io
或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。