读屏软件
移动端 APP 访问无障碍特性,开启读屏模式的设置路径:
iOS: 设置 -> 通用 -> 辅助功能 -> 旁白(VoiceOver) 。
安卓:设置 -> 辅助功能 -> 无障碍 -> TalkBack(不同机型路径可能不一样)
VoiceOver 手势
轻点:选择并朗读项目。
轻点两下:激活所选项目。
左右轻扫:选择下一项或上一项。
三个手指向上或向下轻扫:滑动屏幕上的列表或区。
双指搓擦:快速来回移动两个手指三次(形成“z”字形)以解除提醒,或者返回上一个屏幕。
更多手势可以查看 :VoiceOver - iPhone 使用手册。
安卓的 TalkBack 手势与 VoiceOver 有一些差异
WAI-ARIA
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 可能在小程序设置不生效。
应用
1、非文本元素增加描述和角色属性
通过给非文本元素增加描述和角色属性,元素的内容就可以被读屏软件清晰准确地朗读。
图像可使用 alt 属性描述图像内容,读屏软件会根据 alt 中的内容朗读出 “描述图像内容 图像”。
view 本身是无语义的,可以给元素增加 aria-role 和 aria-label 属性。 读屏软件会朗读出 “label 描述内容 + role 类型”。
<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='返回顶部'
/>
2、整块元素读取
一个元素可能由很多子元素组成。在无障碍模式下,读屏软件只能分别聚焦子元素,单独将每个子元素信息读出来。障碍用户在读屏软件的辅助下,获取到的都是元素零零碎碎的信息,这样的体验很不友好。
类似这样的场景,可以将商品卡片当作一个按钮整块处理。在商品卡片最外层标签加上 aria-role=‘button’,还可以通过 aria-label 标签,将商品信息进行整合,精简描述,缩短商品名字的朗读时间,让障碍用户获得更好的体验。
3、隐藏元素读取
如果不希望部分内容被读出来,可以使用 aria-hidden=‘true’ 来声明,这样读屏时就会忽略这些元素。
<Text aria-hidden='true'>读屏时会忽略这行文本</Text>
上文提到商品卡片的无障碍优化可通过 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='https://img2020.cnblogs.com/other/1992869/202009/1992869-20200923094010512-1049707701.png' lazyLoad />
<View className='goods__info'>商品信息…</View>
</View>
</View>
4、搜索框读取
首页搜索框聚焦后,读屏软件默认会将搜索框中的暗纹读出来。但是障碍用户并不能明显的感知到搜索框元素。
<View aria-role='searchbox'>
<SearchBar />
</View>
5、轮播图读取
轮播图由多个子元素组成,但点击为整块点击,且每个子元素都是图片,读屏软件无法让用户清晰感知元素的含义。
<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>
iOS 和安卓端的差异
1、滑屏手势差异
安卓:双指滑动,根据手势自适应滑动;
iOS:三指滑动,一屏一屏分页滑动。
2、轮播图焦点差异
安卓:焦点位置会跟随子元素滑动消失;
iOS:焦点位置固定不变,不会随子元素滑动而消失。
3、价格读取差异
由于整数部分和小数部分字体大小不同,价格文本是用多个标签实现的。
<View>
¥
<Text>259</Text>
<Text>.2</Text>
</View>
安卓:完整朗读 “259.2元”;
iOS:单独朗读单位、整数、小数,并且会将 “¥” 读作“美元符号”。
4、aria-role=‘button’ 读取差异
安卓:读作“描述+按钮+子元素文本描述”,需借助 aria-hidden=‘true’ 隐藏子元素文本描述,避免信息重复朗读。
iOS:有两种情况。
如果标签同时设置了 aria-label ,则读作“描述 按钮”,不重复朗读子元素文本。
如果标签仅设置了 aria-role=‘button’ ,会继续识别子元素文本,读作“描述+按钮+子元素文本描述”。为避免重复朗读,也需要给子元素加上 aria-hidden=‘true’。