簡體   English   中英

向屏幕閱讀器宣布某些文本的最佳方式是什么(即 role="alert", aria-live="assertive/polite")?

[英]What is the best way to announce some text to screen readers (ie. role="alert", aria-live="assertive/polite")?

我正在創建一個可搜索的 combobox 組件。 它必須是 100% 可訪問的,所以我想告訴屏幕閱讀器在他們打開組件的選項下拉列表時以及在更改其篩選條件時有多少結果可用。

該組件看起來像這樣:

成分

我想我可能需要一個現場區域。 我知道有兩種方法可以做到這一點:

1) role="alert"

這是 AFAIK 最安全的選擇:它在幾年前就已經可以工作了,並且得到了所有主要瀏覽器(Chrome/Edge、FF)和屏幕閱讀器(JAWS、NVDA、VoiceOver/iOS、Talkback)的良好支持。

壞事:它是“粗魯的”,即。 它會打斷屏幕閱讀器的當前通告。 此外,某些瀏覽器會在每個此類公告中添加一個丑陋的“Alert”作為前綴。

因此,例如,如果選項下拉列表被展開(用戶在聚焦過濾器輸入后按下Down鍵),則同時發生兩件事:

  • 過濾器輸入的aria-expandedfalse設置為true ,這使得屏幕閱讀器宣布expanded
  • 下拉菜單現在可見,包含一個實時區域,其中4 of 12 options available, starting with "Badminton"

如果這個實時區域是一個role="alert" ,那么它可能會中斷 (⚡️) expanded的公告,這感覺就像屏幕閱讀器的一個小問題,即。 expa⚡️ 4 of 12 options... .

2) aria-live="polite"

這是更溫和的選項:它將 append 實時區域的內容添加到屏幕閱讀器的當前公告(而不是中斷它),即。 expanded 4 of 12 options...

遺憾的是,據我的測試顯示,JAWS+Chrome 不支持這一點——有人能證實這一點嗎? 如果是這樣,那就太蹩腳了,考慮到它是最常用的桌面組合,而且兩者背后都是跨國公司(可能還有數十億)。

結論

我不能到處使用溫和的aria-live ,我需要弄清楚使用的是哪個瀏覽器,如果是 Chrome,我需要駐留在role="alert"

但還有更多問題:瀏覽器(和/或屏幕閱讀器)處理實時區域的方式似乎存在嚴重差異:

  • 如果它首先hidden (即hidden屬性,或display: none )然后變得可見,有些人在識別活動區域時會遇到問題。 然后它就不會被視為活動區域。
  • 有些人會立即宣布這種可見的直播區域的內容,而另一些人則只是忽略他們的初始內容(他們只會宣布對其進行更改)。
  • 有些人宣布一個role="alert"元素,即使它在頁面加載時已經存在,其他人則沒有(我認為后者是正確的,因為據我所知,實時區域應該宣布內容的變化,而不是最初已經存在的內容)

所以這個話題比我希望的要復雜得多。 最簡單的解決方案可能如下所示:每次發布公告時,只需 append 在 DOM 末尾添加一個視覺上隱藏的role="alert"元素。 然后,幾秒鍾后,再次將其取下。 但這對我來說很難看。 我寧願讓我的活動區域就在我的組件內部,可見用戶也可以看到它,或者至少看到它的一部分:在屏幕截圖上,您可以看到4 of 12 options for filter "d" ,但對於屏幕閱讀器來說,宣布了相同的文本,加上一些更多的細節,即。 starting with option "Badminton" 將視覺和屏幕閱讀器公告放在同一個地方對我來說是一種很好的做法,所以我不會輕易忘記后者,否則我會很快發現一些錯誤(否則可能不可見)。

所以我的問題是:是否有現有的腳本或庫可以可靠地解決這個問題並為最常見的瀏覽器/屏幕閱讀器組合提供最佳體驗?

謝謝你。

禮貌的居住地區應該是首選。 正如您自己注意到的那樣,警報會打斷當前的講話,這很不禮貌。 前綴“警報”。 自動添加有時甚至會讓人感到有點害怕。

正如您所注意到的,禮貌的實時區域在每個瀏覽器 + 屏幕閱讀器組合上的工作方式略有不同。 其中一些差異是有意為之,另一些只是錯誤,還有一些僅僅是因為官方規范沒有明確定義任何特定行為。 正如你所說,這使得整個事情變得非常復雜。 遺憾的是,我沒有通用的解決方案。 為了處理所有情況,您需要進行用戶代理檢測。

讓我們看看今天(2022 年 5 月)我們在實時區域中遇到的各種問題或注意點。 我沒有官方參考,以下僅是我多年來的觀察:

實時區域檢測

只有當元素添加到 DOM 時存在 aria-live 屬性並且屏幕閱讀器可見時,才會成功考慮活動區域。

特別是,這意味着在將元素添加到 DOM 后設置 aria-live 屬性時,當元素顯示:無,可見性:隱藏時,當屬性 aria-hidden 或hidden 被設置,或者當 size 為 0 時。即使稍后刪除 hidding 屬性,它也不起作用。

公示時間

必須公布直播區域內容的僅有兩種情況是:

  • 當元素被添加到 DOM 中時
  • 當元素的內容發生變化時

對於所有其他情況,規范中沒有明確定義。 特別是,直接出現在 HTML 代碼中的初始內容可能不會被公布,據我觀察,我使用過的瀏覽器都沒有在頁面加載時公布初始內容。

中斷

當添加一個自信的現場區域時,語音通常總是被打斷。 禮貌的實時區域更新不應打斷語音。

但是,對於許多瀏覽器+屏幕閱讀器的組合,當前正在閱讀的內容會被關閉:

  • 當 aria-live 元素從 DOM 中移除時
  • 當它的內容被清空時

例如,iOS 和 mac 下的 VoiceOver 就是這種情況。

因此,如果您有可能連續快速地說出多條消息,則不應只用新消息替換舊消息。 您可以采用幾種策略:

  • 只需 append 條新消息到現有的實時區域
  • 每次創建新的活動區域
  • 僅當最后一條消息早於幾秒前時,才清除實時區域內容或將其從 DOM 中刪除

但是,請注意,這還不是全部。

重復或不重復

對於某些瀏覽器 + 屏幕閱讀器組合,如果您只是在直播區域的末尾宣布 append 條新消息,則整個內容從頭開始一遍又一遍地重復。 簡而言之,每次有變化時都會閱讀整個內容,即使是沒有變化的部分。

理論上,該標准提供了兩個屬性aria-atomicaria-relevant來控制這種行為。 默認值是 aria-atopic=false 和 aria-relevant=additions,這意味着只有新內容必須被閱讀,沒有改變的內容不應該被再次閱讀。

然而,在實踐中:

  • 帶有 Jaws 和 NVDA 的 Chrome 完全忽略了這些屬性。 無論如何,每次更改時都會閱讀全部內容。
  • 使用 Firefox 和 Jaws,當顯式設置 aria-relevant 屬性時,aria-live 區域不再有效
  • 對於 Safari 的至少某些版本,如果未明確設置 aria-relevant=additions,aria-live 區域將不起作用
  • 在某些版本的 Chrome 中,如果出於任何原因你想說兩次相同的消息,替換內容是行不通的,即使你首先替換為空字符串,然后再替換為內容

如果我們為每條消息創建一個新的活動區域,我們是否安全? 劇透警報:不!

公告順序

當多個實時區域被添加到 DOM 或快速更新時,沒有人說必須首先宣布哪個。

  • Safari iOS 似乎處理正確,即按更新順序讀取內容。 我不知道在 mac 上。
  • 使用 Chrome 以及 Jaws 和 NVDA,快速更新幾個活動區域似乎使它們在 DOM 中以與 position 相反的順序讀取。

結論

目前,看起來最安全的是為每條消息創建新的禮貌生活區域。 您可以重復使用它們,但前提是新消息不會很快到達,或者它們偶爾被打斷也沒關系。

對於您的特殊情況,我會說一個重復使用的禮貌活動區域就足夠了。 但當然最好的辦法是測試盡可能多的組合。

祝你好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM