最近,我需要为标题元素中的各个字符设置动画。我希望有一个类似于css的方便的css专用解决方案:nth-child(i),但不幸的是不存在。因此,我决定研究如何实现类似且可访问的内容。
的html我的第一个想法是<span>手动将每个字符包装在单独的元素中。
<h1>
<span>t</span>
<span>e</span>
<span>x</span>
<span>t</span>
</h1>
但是,此方法存在两个问题:
辅助功能:通过这样分割文本,屏幕阅读器将单独读取每个字符,这对依赖屏幕阅读器的人们来说是一种痛苦的体验。可伸缩性:这样写出整个单词或句子是一个烦人的过程,每次都必须手动重复,并且不适用于动态加载的文本。具有html和javascript的可访问且可扩展的解决方案我在css-irl上找到了解决这些问题的解决方案,使用aria元素来实现可访问性,并使用javascript来自动执行文本拆分。它以您想要拆分的文本作为输入,并以如下方式返回它:
<h1 aria-label=text>
<span aria-hidden=true>t</span>
<span aria-hidden=true>e</span>
<span aria-hidden=true>x</span>
<span aria-hidden=true>t</span>
</h1>
屏幕阅读器将阅读内部定义的文本,aria-label但忽略标记为的元素aria-hidden=true。但是,当我在mac上的voiceover上尝试此操作时,我发现还必须向role父级添加一个元素才能使其正常工作。
<h1 aria-label=text role=heading> ... </h1>
反应组件由于我在react中做了很多工作,因此我决定在可重用组件中创建一个类似的解决方案。
从前面的示例中我们知道,我们至少有两个变量信息:必须显示的文本(this.props.copy)和元素的角色(this.props.role)。
基于此,我们可以从创建splittext可重用组件开始:
<splittext copy=this is the text that will be split role=heading />
在splittext组件的render函数中,我们首先要使用aria-label={this.props.copy}和渲染一个父元素role={this.props.role}。这将使屏幕阅读器阅读原始文本。
然后,我们需要遍历副本,并使用返回返回包裹在span元素中的每个元素aria-hidden=true。这将在视觉上呈现字符串的每个字符,但屏幕阅读器将跳过它。我们可以使用.split()函数将文本变成数组来遍历文本。
render(){
return(
<span aria-label={this.props.copy} role={this.props.role}>
{this.props.copy.split().map(function(char, index){
return <span aria-hidden=true key={index}>{char}</span>;
})}
</span>
);
}
在此扩展现在我们有了基础,我们还可以扩展此逻辑,并在其中添加更多功能splittext,例如自定义类名称或条件样式。我将编写第二个教程,在其中我们将更深入地介绍一些示例。