我能否防止屏幕阅读器读取 :after 伪元素?

35
请考虑以下 HTML 标记:
<label class="required" for="email-address">
  Email Address
  <span class="audible">Required</span>
</label>
<input type="text" id="email-address" placeholder="Company@address.com">

除此之外,我还有以下的CSS:

.required:after {
  color: red
  content: "*";
  /* ... */
}

当我聚焦在该字段上时,屏幕阅读器将会朗读出:“需要电子邮件地址,并有星号”。我想只使用CSS来显示一个视觉上的星号,但是我不希望被屏幕阅读器朗读。这是否可能?

或者说,这种情况是否足够普遍,以至于屏幕阅读器和用户会忽略星号或调整设置。也就是说,这不是一个真正的问题吗?


这是可行的答案 https://dev59.com/6VYN5IYBdhLWcg3wb3sX#47451397 - Londeren
6个回答

14

试一下这个,它使用媒体查询针对屏幕阅读器并隐藏星号。

@media reader, speech, aural {
    .required:after {
        display: none;
        visibility: hidden;
    }
}

更新:

由于我的初始解决方案得到的支持似乎不是很好,我想到了一个替代方案。我意识到,确保屏幕阅读器不读取它(没有额外标记)的唯一方法是根本不使用星号!但是,您可以添加带有 CSS 的图像来看起来像星号,如下所示:

.required:after {
    content:'';
    display: inline-block;
    width: .5em;
    height: .5em;
    background-image: url(http://upload.wikimedia.org/wikipedia/commons/b/b5/Asterisk.svg);
    background-size: .5em .5em;    
    vertical-align: top;
    margin-left: .15em;
    margin-top: .1em;
}

http://jsfiddle.net/3a1dvdag/


2
如果你采用这种方法,你可以直接使用content:none。 - Adam Hughes
1
这正是我正在寻找的。有关于此的支持信息吗? - Tim
Aural在规范中,因此应该是最常实现的。http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors - Adam Hughes
我在语音朗读、NVDA和JAWS(最新版本)上进行了测试。只有JAWS似乎可以做到。但对我来说可能已经足够了。 - Tim
@Tim 我刚刚更新了答案,提供了一种更好的方法,应该有更好的支持。不过,由于我没有可用的屏幕阅读器,所以无法测试它。 - Sam

7

我会在这里提供一个解决方案,因为目前还没有最终答案,这是一个被广泛讨论的话题。

上面@Sam提供的解决方案将来会是最好的选择。到目前为止,没有浏览器支持@media aural, speech媒体查询,所以如果您提供它,它只能在不久的将来起作用。

还有其他方法可以隐藏伪元素使其无法被屏幕阅读器读取吗?

有,但有限制。您可以使用“私人使用Unicode字符集”。由于这些字符是私人使用的,屏幕阅读器无法发音并因此忽略该字符。

如果这不是一个选项,请尝试使用带有aria-hidden="true"<span><i>元素。虽然不像伪元素那么干净,但至少您可以完全控制内容。

<button type="button">
    <span class="i i-arrow-down" aria-hidden="true">Label
</button>

1
经过研究,我认为添加元素而不是使用伪元素可能是一个不错的选择。 - Tim
2
@Tim 另一个选择是始终在<button>标签上提供aria-label。然后,内容(包括<i>元素和实际标签)都将被忽略,而是读取aria-label。我已在VoiceOver上测试过它,在那里可以正常工作,我将在JAWS和其他屏幕阅读器上进行测试。我会尽快反馈结果。 - Warre Buysse
@Tim 同时我也在 Jaws 上测试过了,效果完美。 - Warre Buysse

7

有一种语法可以使用斜杠作为分隔符来设置伪元素的alt文本。我们可以将其留空以表明该元素应被忽略(就像通常在img标记中所做的那样),例如:

.required:after {
    color: red
    content: "*" / "";
    ......
}

这个来源表明在2020年,浏览器的支持情况还算可以。我已经在MacOS上用Chrome和VoiceOver进行了测试,现在它可以正常工作(与表格所示相反),因此希望现在的支持已经非常好了。

https://a11ysupport.io/tests/tech__css__css_generated_content_alt


3
不幸的是,目前这在Firefox和Safari上无法正常工作。 - Matthieu Boileau

3

目前我认为只存在一些解决方法,比如使用HTML元素和aria-hidden的组合,或者浏览器实现的有限支持,例如实现了CSS3语音模块

注意,该模块仍处于候选推荐级别,但应该提供更准确的控制,以便在朗读时决定哪些内容需要被读出来,哪些不需要。

如果浏览器的支持是完美的,那么一个好的回答就是:

使用CSS3语音模块。

但是,这是Web,浏览器支持并不完美,因此即使在这个问题被问了4年后,我推荐使用spanaria-hidden="true"的组合。

但需要知道的是,尽管aria-hidden属性确实可以防止元素内容被朗读,但它也会将其存在隐藏起来。差别微妙,但speak属性不会通过在说出属于元素的子元素数量时提到它来隐藏元素的存在。

例如,考虑以下代码:

<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>What a beautiful day!</title>
  <style type="text/css">
  body {
    counter-reset: headers;
  }

  h2::before {
    counter-increment: headers;
    content: counter(headers, upper-roman);
    speak: none;
  }
  </style>
</head>
<body>
  <h2>Early morning</h2>
  <h2>Lunch</h2>
  <h2>Before dinner</h2>
</body>
</html>

以下是支持Web浏览器(此处为Firefox 59)上Voice Over读取Lunch元素的内容:

Voice Over on Firefox 59 result for CSS speak: none property

它会计算(伪元素算作一个)speak:none;元素,但不会朗读它。

使用aria-hidden可以使元素完全不被计算。

我尚未尝试其他屏幕阅读器,因此结果可能会有所不同。


1
如果您为图标使用单独的 span 标签,您可以应用一个 "aria hidden" 标签来防止屏幕阅读器朗读它。不过我不确定支持程度如何。
<label class="required" for="email-address">Email Address 
<span class="icon" aria-hidden="true"></span>
<span class="audible">Required</span>  </label>
<input type="text" id="email-address" placeholder="Company@address.com">

在W3C规范中获取更多信息


是的,我可能得这样做。但我在想是否有一种方法可以不添加额外的标记 - 只使用 CSS。 - Tim

-1
创建一个带有属性` speak:never`的CSS类。

你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人能够确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接