A11Y 101: 构建可访问性React应用的技巧

特别声明:如果您喜欢小站的内容,可以点击年卡¥199.00元(原价: ¥598元)季卡¥78.00元(原价: ¥168元)月卡¥28.00元(原价: ¥68元)进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

众所周之,React目前是前端领域最为流行的JavaScript框架之一,很多Web开发都是基于React进行Web开发。但据 WebAIM Million统计分析可得知“使用React框架开发的Web应用或Web页面就可访问性方面而言,其错误要比一般的主页多出5.7%”。而且在社区中普遍认为,基于React开发的Web应用对于Web可访问性本来就差,而且开发者无法很好的基于React框架开发出具有可访问性的Web应用。事实上这是一种错误的认知,基于React能不能开发出具有可访问性的Web应用和React本身并没有太多的关系,因为开发一个具有可访问性的Web应用更多的是和HTML和WAI-ARIA有着紧密的关联。换句说,基于React开发具有可访问性的Web应用,应该注意些什么,以及如何更好的开发更具可访问性的Web应用。这是今天要和大家一起聊的话题。

为什么说基于React开发的应用更不具可访问性

为什么说基于React框架开发的Web应用或页面更不具可访问性呢?” 这除了源于错误的认知之外,还有一定的客观因素存在的。其中一个原因就是基于React框架开发Web应用时会(或者可能会)使用组件库。如果使用的组件库自身就不具有Web可访问性的话,就会造成React开发的应用不具Web可访问性。换句话说,使用其他组件(特别是第三方组件)进行开发,要改善Web可访问性而言是件痛苦的事情,而且成本也是极高的。因为在这个场景之下,要彻底优化Web可访问性就需要去修改组件。

要修改第三方组件,估计成本会极大,甚至是不太可能。

另外,那就是基于React框架开发者自身就存在一定的问题。比如 @BrittanyIRL 在2019年React Conf大会上分享的话题中提到的:

简单地说,很多开发者,特别是基于React这样的JavaScript框架开发者而言,已经习惯了只使用<div><span>来构建自己的模板(Template)。也就是说,不基于语义化的HTML进行Web开发,要让Web应用更具可访问性,难度是极大的,即使优化起来成本也很高。

另外一个原因正如 @estellevw 在Twitter上的吐槽

用一句话来概括的话,就是:

在编写HTML的时候,对于无任何语义化的<div><span>标签应该被最后使用,即 找不到任何有语义化的标签时才使用这两个标签

如果要仅基于divspan进行开发,要开发具有Web可访问性的Web应用或Web页面就需要强度的依赖于WAI-ARIA相关的技术。

有关于WAI-ARIA更详细的介绍可以阅读《A11Y 101:WAI-ARIA初探》一文,或者阅读下面相关教程:

如果你曾经接触过Web可访问性相关的知识的话,你应该知道。针对于Web开发而言,构建可访问性的Web应用可以根据相关的规范(即 网络内容无障碍指南,也就是大家所说的WCAG指南)来做开发。另外和WCAG相关的规范还有:

基于React开发Web应用和普通Web应用开发有何不同

React框架还没有出现之前(或者说不基于任何JavaScript框架开发Web应用),都是基于HTML来进行开发。HTML是构建Web应用最基本的部分之一,但对于可访问的Web应用而言,在原有的DOM基础上会有另一个解析树,即 AOM树(可访问性树)。粗略地说,AOM是DOM树的一个子集。我们可以用下图来描述AOM和DOM之间的关系:

对于用户界面和辅助技术,也可以用AOM和DOM来描述它们之间的关系:

但是,基于React框架开发的Web应用和我们平时使用HTML开发的Web应用还是有很大区别的。在React中,它通过构建一个“虚拟DOM”来替代DOM,执行DOM更新的替代方法(直接更新DOM的开销可能相当大)。对于每个DOM对象,虚拟DOM中将有一个对应的对象。

因此,虽然虚拟DOM本质上只是DOM的克隆,但它没有修改用户所看到的内容的能力。这实际上使整个过程更快,因为可以“批处理”对虚拟DOM的更改,并且可以在事件循环结束时进行差异(diff)操作

当你渲染一个JSX元素时,每个虚拟DOM节点将被更新,然后在更新之前的虚拟DOM和更新之后的现在的虚拟DOM之间执行一个“差异操作”,并能够理解哪些对象被更改了。

在DOM中只修改已经更改的节点

虚拟DOM是一个非常重要也是非常复杂的概念,如果你想了解有关于虚拟DOM更多的知识,可以阅读:

先抛开虚拟DOM不聊,根据AOM和DOM之间的关系,我们可以把虚拟DOM结合进来,那么用下图来描述:

换句话说,即使你对虚拟DOM不太了解也不过于太担心,因为基于React构建可访问的Web应用和以往构建可访问的Web应用相同,采用的也是相同的规范,只不过在写模板(Template)时有所差异。即JSX语法编写模板。如果你不熟悉它,建议你花点时间阅读以下资源:

React中如何构建可访问的Web应用

有了这些基础,我们就来开始看看如何在React环境下构建更具可访问性的Web应用。

HTML属性和保留字

熟悉JSX或了解React开发的同学都知道,在React中编写HTML时要记住的一件事是,HTML属性需要用camelCase(驼峰)编写。例如,tabindex需要写成tabIndex。这个规则的例外是,任何data-*aria-*aria-*是ARIA中的属性集,比如aria-labelaria-hidden等)属性仍然按照以往的写法,不需要换成驼峰写法。

JSX是JavaScript中的一种扩展语法,而JavaScript中还有一些特定HTML属性名匹配的保留字。这些不能以你期望的方式来书写。比如for就是JavaScript中的一个保留字,在JavaScript中它用于循环遍历,而在React中<label>元素时,可以使用for属性与相应的表单控件绑定在一起,那么这个时候,在JSX中就需要把for换成htmlFor属性。另外,class也是JavaScript中的保留字,它在HTML中是用来给元素声明类名,那么在React中它就得换成className。除此之外,可能还有更多属性需要关注,但到目前为止,我发现JavaScript中保留字和HTML属性之间只有这些冲突。

<form>
    <div className="control">
        <label htmlFor="user">用户名:</label>
        <input type="text" aria-required={true} name="user" id="user" />
    </div>
</form>

语义化的HTML

语义化的HTML指的是具有语义的HTML标签,它使用针对其目的而全名的元素。语义化的HTML也是构建可访问Web应用的基础,利用多种HTML元素来强化你的Web应用中的信息通常可以使用你直接构建更具可访问性的Web应用。但正如前面 @BrittanyIRL提到的,如今天很多使用React(或类似于React框架,比如Vue)的开发者过度的依赖于<div><span>这种无语义化的HTML标签,甚至很多开发者都不知道如何在开发中使用有语义化的标签。

正因为,使用类似React框架开发的Web应用可能只能看到<div><span>标签,也让众多开发者造成一种误解:

使用React框架开发的Web应用,只能使用<div><span>

这也让React背上了不可构建可访问性Web应用的锅。换句话说,我们使用React框架来开发Web应该,不应该只使用这两个无语义的HTML标签,我们更应该在写模板(JSX模板)时考虑有语义的HTML。这样做有几个原因:

剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/a11y/a11y-making-react-apps-more-accessibility-tips.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部