隐藏元素但为屏幕阅读器保留(不能使用 display:none、visibility:hidden 或 opacity:0)

Hide Element but Preserve for Screen Readers (can't use display:none, visibility:hidden, or opacity:0)

我的 HTML 中有一个音频元素,其唯一目的是通过屏幕 Reader 向盲人用户发出通知。这是一个 DIV,但普通用户看不到它。

声明某物的方法是通过创建一个带有 role=alert 的元素(没有其他方法可以做到这一点,没有 JS 函数可以直接 "speak" 到 reader,例如):

<!-- This element can be dynamically added OR shown (via JS) to make a Screen Reader announcement -->
<div role="alert">This will be announced to Screen Readers.</div>

但是,我无法让普通用户看到此 "audio assistant" 元素。

1) 无法使用display: none; -> 屏幕 Reader 不会拾取它

2) 无法使用 visibility: hidden; -> 屏幕 Reader 无法拾取

3) 不能用opacity: 0; -> 因为space被占了,布局必须完全一样

我找到了这个解决方案:

div { position: absolute; left: -999em; }

效果很好,解决了我的问题。但这有点骇人听闻。我想问一下:有没有更好、更标准的方法来解决这个问题?

我不确定这是否是 "better" 方式,但这会把它隐藏起来。

div {
  overflow:hidden;
  height:0;
  width:0;
}

通常的做法是使用 CSS 在视觉上隐藏元素,但允许屏幕 reader 用户发现它。它不一定被视为 "hack".

需要的 CSS 个属性比您尝试的要多。有关详细信息,请参阅 What is sr-only in Bootstrap 3?

此外,您可以搜索 "visually-hidden" class。

sr-onlyvisually-hidden 都是通用名称,用于命名视觉上隐藏元素的 class。

还有,你对role="alert"的理解不太准确。

The way to announce something is by creating an element with role=alert (no other way to do it, there's no JS function to directly "speak" to a reader, for example):

role="alert" 有一个隐含的 aria-live="assertive"。具有 aria-live 的元素将在 reader 屏幕上宣布对该元素的 更改 。它不会自动宣布该元素。例如,

<div id="foo" aria-live="polite"></div>
<button onclick="document.getElementById("foo").innerHTML = 'hello'">update</button>

当我单击该按钮时,文本将被注入

并宣布新文本。

一般来说,您想使用 aria-live="polite" 而不是 aria-live="assertive"。当你使用 role="alert" 时,你会得到 aria-live="assertive".

因此,如果您的页面正在更新其内容,那么使用 aria-live 是正确的做法。但它不会因为您的页面加载而导致某些内容被宣布。

屏幕 reader 用户可以使用屏幕 reader 中定义的快速导航键(例如 H 转到下一个标题 [h1、h2、h3 等],或 T 转到下一个 table,或 L 转到到下一个列表等),前提是您的 HTML 使用语义元素(例如

、、
    等)。如果您有对视力正常的用户隐藏的文本,那么屏幕 reader 用户可以找到该文本,而无需您强制自动阅读它。