無障礙開發(十)之讀屏軟件讀什么?


例如使用了 a 標簽制作了按鈕,如果不進行額外的優化,讀屏軟件在朗讀時會讀作"文字內容 鏈接",但實際上該 a 標簽是用作按鈕使用,因此可以在標簽上添加 role="button" 屬性。此時,讀屏軟件會讀作"文字內容 按鈕"

可以看到,讀屏軟件在朗讀時會在結尾朗讀出元素的屬性,這也是無障礙優化中重要的一環。無障礙優化就是要解決如何使得元素的屬性被正確識別,如何使得元素的內容被清晰准確地朗讀,如何排除干擾元素等問題。在了解 WeRead

H5 的無障礙優化處理之前,首先需要了解 Web 無障礙開發的基礎知識,及讀屏軟件的工作方式(以 Apple VoiceOver 為例),可以參考以下資料:

Android和iOS表現

安卓和ios的讀法可能會有不同,屬性在不同的瀏覽器上支持不同

DOM 的順序很重要

讀屏軟件在讀屏時默認按照 DOM 的順序朗讀,因此如果 DOM 的順序與內容的語義順序不一致,例如使用了 flex-direction: row-reverse; 使得內容的順序倒序顯示,會使得內容難以理解。因此盡量避免使用會影響到 DOM 視

覺順序的樣式,如果無法避免,需要手動設置 tabIndex 屬性,告知讀屏軟件正確的內容順序。

為非文本元素提供文本說明

關於Image

圖片或者動畫均需提供 alt 信息,對於某些用於裝飾性的圖片,則需設置 alt 為空,使得讀屏軟件可以忽略此元素。如圖用於裝飾頁頭的圖片,實際並沒有傳遞有價值的信息。

對於圖表文件,alt 屬性的設置則需要簡明扼要的表達出圖表的信息,並不用把里面的細節都詳細得描述出來。例如下面的圖alt 信息設置為銷售額從 1996 年到 2004 年間持續穩定增長,從 400 萬增長到了 1600 萬。並不需要把每一年的

增長額都詳細得描述出來。

<img> 標簽需要加上 alt 屬性,讀屏軟件會自動讀出 alt 的內容,例如 alt 內容為"一只目光洶洶凝視遠方的貓",那么會被讀作"一只目光洶洶凝視遠方的貓 圖像"。如果沒有添加 alt 屬性,那么僅會讀作"圖像",視障用戶會完全無法

理解其實際含義。但是,當 <img> 標簽出現在 <a> 標簽內部,作為一個圖像鏈接時,對於放在鏈接里面的圖片,如果已經有文字的說明,alt 也設置為空,這樣避免讀屏軟件重復同樣的內容。如下面的 HTML:

<href=”http://apple.com/iphone/”> <img src=”iphone.jpg” alt=””>Apple iPhone </a>

 a的內容已經指明了這是個蘋果手機,img 的 alt屬性就沒必要再設置一次了。否則讀屏軟件會連續讀兩次重復的內容,引起混亂。

視頻使用 title 屬性

與上面的 <img> 標簽相似,<video> 標簽需要加上 title 屬性,例如 title 內容為"一只正在奔跑的貓",那么會被讀作一只正在奔跑的貓 視頻"

使用語義化的元素

盡量使用語義化標簽

語義化的 HTML 標簽,例如 <header> <footer> <nav> <section> <main> <aside> <button>,使用語義化的標簽,主要影響兩個方面:

  • 選中元素時是否會整塊選中

  • 朗讀時結尾會加上怎樣的修飾詞

其中默認設置下,目前僅 <button> 標簽可以使得選中元素時會整塊選中,而不單獨選中子元素。至於修飾詞這里列舉具體的情況:

  • <header> 讀作"xxx 橫幅 標志性內容"。

  • <footer> 讀作"xxx 頁腳 標志性內容"。

  • <nav> 讀作"xxx 導航 標志性內容"。

  • <section> 僅讀作"xxx",沒有結尾修飾詞。

  • <main> 讀作"xxx 主要 標志性內容"。

  • <aside> 讀作"xxx 補充 標志性內容"。

  • <button> 讀作"xxx 按鈕"。

  • <a> 讀作"xxx 鏈接"。

實際上,在瀏覽器內部,使用語義化標簽會隱式加上特定的 role 屬性,最后朗讀時的結尾修飾詞也正是這些 role 屬性的值以及分類,其他 role 的值朗讀時也可以以此類推,而以上標簽與 role 屬性具體對應的關系如下:

以上 role 屬性值的分類大多數都屬於標志性內容

role 屬性

如果出於其他考慮,使用了非對應語義的標簽,例如開頭提到的使用 a 標簽實現按鈕,就需要添加 role="button" 屬性來聲明這是一個按鈕。同理,其他類似情況也可以這樣處理,主要的就是影響朗讀時的修飾詞

禁用狀態使用 disabled 屬性

使用特定的 class 來增加禁用態樣式是常見的手法,但由於 class 語義並不能被讀屏軟件識別,因此讀屏時無法知道當前處於禁用態。可以改為使用 disabled 屬性實現禁用態,例如:

<input type="search" name="q" placeholder="請輸入用戶名" aria-label="搜索用戶" disabled/> 
/* 禁用態樣式 */ input[disabled] { opacity: .5; }

會讀作 搜索用戶 請輸入用戶名 變暗 搜索欄讀屏軟件會用"變暗"這個詞表示搜索欄處於不可用的狀態而對於沒有 disabled 屬性的標簽,例如 a 標簽,可以使用 aria-disabled 屬性達到同樣的效果

可使用 aria 標簽向不存在原生語義的元素添加語義

  • aria-label="screen reader only label",用於添加朗讀時的描述,讀屏時會讀出其中的內容,而忽略標簽的原有的文字,例如為 a 標簽同時添加 role="button" 和 aria-label="額外的按鈕描述",最終會朗讀

           成"額外的按鈕描述 按鈕"。

  • aria-controls="main",用於給操作按鈕關聯控制區域,VoiceOver 上這個屬性沒有任何作用,但 PC 讀屏軟件中,添加了該屬性后,可以把焦點從按鈕快速移動到被控制區域。

  • aria-live="true",添加了該屬性的元素,在其內容發生變化時,讀屏軟件會自動讀出變化后的新內容。可以用於會動態刷新的元素,例如發現卡片上的“XXX人參與活動”,書城的換一批功能,用於監聽實時變化的數據。實際

    效果可以參考這個 demo

動畫

可在 iOS 下通過 CSS 選擇器 @media(prefers-reduced-motion) 來針對開啟了“避免動畫”的用戶取消動畫。

隱藏屏幕外的元素

確保屏幕外的內容已通過 display: none 或 visibility: hidden 隱藏(如浮動出現的 alert 和 banner 等),如沒有隱藏,讀屏軟件仍會讀出元素內容但屏幕外的元素通常不希望被讀出,如果不方便使用樣式進行隱藏,可以為

元素添加 aria-hidden="true" 屬性,元素則會被讀屏軟件忽略。

隱藏的內容分為兩種,一種是為了布局的需要,在條件滿足的情況下才會顯示出來;另一種是只給讀屏軟件讀的內容:有時候我們為了使讀屏軟件更准確的讀取信息,會提供一些額外的描述來達到此效果,但為了不給正常用戶帶來困擾,

這些內容對正常用戶來說是隱藏起來的。隱藏內容我們通常用 display:none 或者 visibility:hidden 來表示,但讀屏軟件同樣也會忽略這類內容。那如何隱藏內容又能使讀屏軟件讀出來呢?另外一種隱藏內容的方式是使用絕對定

位使得內容不出現在當前屏幕上,如:{position:absolute;top:-30000px;}所以在選擇使用哪種方式隱藏內容時就需要慎重考慮,display:none visibility:hidden 對任何人都是隱藏的,如果想只給讀屏軟件讀到就需要使

用上面的絕對定位方式。著作權歸作者所有。

空格的使用

我們可能會遇到一種情況例如:招商銀行卡(9326),讀屏軟件子讀屏的時候會讀為“招商銀行卡九千三百二十六”但是這個並不是盲人用戶期待聽到的,或者讀為“招商銀行卡九三四六”會更合適,所

以我們要如何處理呢?有兩種想法

第一種:將9346這幾個“數字”分別替換成“中文”,但是需要注意的就是因為銀行卡號哪個數字都有可能,所以我們需要做一個數字和中文的映射

第二種:在9326這幾個數字中間分別加一個空格,這樣因為每個數字都不挨着,中間有一個看不見的空格,所以讀屏軟件在讀屏的時候就不會讀成“九千三百二十六”而是“九三四六”

中文的使用

在某些情況下如果有些讀法不對可以替換為中文

常用場景

一、圖像的編寫

如上文所述,圖像需要補充文字描述,補充時需要使用具體的內容標題,例如書籍封面,可以使用書籍名稱,而不要直接統一描述為"書籍封面",同理用戶頭像也應該使用用戶名作為描述文字。

二、按鈕的編寫

在 H5 中,為了避免一些瀏覽器默認樣式的干擾,以及制作點擊效果具體原因,目前采用 a 標簽實現。但從無障礙的角度考慮,a 標簽默認會被當做鏈接處理,屏時會讀作"鏈接內的文字 鏈接"。

  • 基礎無障礙適配

需要加上 aria="button" 屬性,例如:

<a class="test_btn" role="button" href="javascript:;">文字</a>

讀屏時會讀出"文字 按鈕"。

  • 增加描述文字

如果 a 標簽內本身沒有文字,例如以圖片、背景色和邊框制作的按鈕,還需要加上 aria-label="描述文字",讀屏時會讀作"描述文字 按鈕"的形式。當 a 標簽內的文字對於視障人士不足以描述清楚按鈕作用時(例如需要結合上下的元

素,或者結合按鈕本身的背景圖才能理解按鈕的含義時),也可以加上 aria-label 屬性,aria-label 的內容會被優先讀出,例如:

<a class="test_btn" role="button" href="javascript:;" aria-label="更完整的描述">文字</a>

讀屏時會讀出"更完整的描述 按鈕"。

  • 多重標簽嵌套 

另外 a 標簽內容如果有嵌套的標簽,並不會影響文字被讀出,例如:

<a class="test_btn" role="button" href="javascript:;">

    <span class="test_btn_inner">

        <span class="test_btn_inner_text">文字</span>

    </span>

</a>

讀屏時仍會讀出"文字 按鈕"。

三、整塊可點擊元素的編寫

在遇到 banner 等本身由多個子元素組成,但點擊時為整塊點擊的元素,需要分為兩種情況考慮

  • 使用 a 標簽實現

如果使用了默認的點擊效果,即使用了 a 標簽實現外層框,讀屏時子元素會被分別選中,但實際上單獨讀出每個子元素不能表達按鈕整體的完整含義。因此,我們建議整塊當作按鈕處理,但一般無需添加 aria-label讓讀屏軟件直接

按 DOM 順序讀出子元素的文字內容即可,例如:

<a class="welcomeBonus_packet" href="javascript:;" role="button" @click="packetRedeem"> <div class="welcomeBonus_packet_info"> <div class="welcomeBonus_packet_info_title">主標題內容文字</div> <div class="welcomeBonus_packet_info_desc">描述文字</div> </div> <div class="welcomeBonus_packet_btn"> <span>提示文字</span> </div> </a>

會被讀作"主標題內容文字 描述文字 提示文字 按鈕",視障人士會清楚這是整體點擊的按鈕,並且了解到其作用。如果部分內容不希望被讀出來,精簡朗讀文案的時長,例如作用不大的輔助語句,可以單獨添加 aria-hidden="true"

需要注意,可點擊元素點擊后跳轉頁面通常采用 role="link" 聲明而點擊后進行一些操作則通常采用 role="button" 聲明讀屏的時候結尾分別為"鏈接"和"按鈕",但本場景下建議統一使用 role="button"或者role="text"或者role="heading",因為 role="link" 並不會讓元素整塊被識別,實際體驗上,整體識別能帶來更好的體驗,而視障人士對於"鏈接"和"按鈕"的理解包容度也比較高。但是role="button"還存在的一個問題就是在讀屏軟件最后會讀出角色"按鈕",有些場景並不適用。

  • 使用語義化標簽實現

如果無需使用默認的點擊效果,建議使用語義化的標簽實現外層框,例如 sectionaside,這樣用戶在使用“container 模式”進行讀屏時,元素會直接被整體識別,而不會單獨讀出子元素。

以 VoiceOver 為例,雙指旋轉可以調節焦點選擇的模式,”container 模式“下焦點僅會被 section 這類外層容器捕捉。 

 

  • 使用aria-hidden實現

如果使用了默認的點擊效果,即使用了 a 標簽實現外層框,讀屏時子元素會被分別選中,但實際上單獨讀出每個子元素不能表達按鈕整體的完整含義,所以我們可以使用aria-hidden對a標簽中的子元素進行隱藏,這樣隱藏的部分就不會獲得焦點,屏幕閱讀器就不會讀,再給a標簽添加role為button、text、heading等都可以,另外獲得焦點時讀的內容可以使用js給a標簽動態添加aria-label

<a class="welcomeBonus_packet" href="javascript:;" role="button"> <div class="welcomeBonus_packet_info" aria-hidden="true"> <div class="welcomeBonus_packet_info_title">主標題內容文字</div> <div class="welcomeBonus_packet_info_desc">描述文字</div> </div> <div class="welcomeBonus_packet_btn" aria-hidden="true"> <span>提示文字</span> </div> </a>
  • 實例

實例一:

<div class="pay-total" role="text">

      <strong class="JS-pay-total">

    <span class="JS-pay-total-icon">¥</span>

    14

    <em>.22</em>

  </strong>

</div>

問題:ios中屏幕閱讀器將支付金額14.26分開讀,並且不讀元

原因:父元素包含很多子元素,每次都是單獨獲取,無法獲取整塊元素

調整:設置role="text"/role="heading",並將調整好的數據賦值給aria-label,並對JS-pay-total類所在的元素設置aria-hidden="true"

代碼:

HTML:

<div class="pay-total" role="text">

      <strong class="JS-pay-total" aria-hidden="true">

    <span class="JS-pay-total-icon">¥</span>

    14

    <em>.22</em>

  </strong>

</div>

 

Javascript:

if (total[1].length > 1) {
        total[2] = total[1].substr(1,1) == '0' ? '零' : total[1].substr(1,1);
        total[3] = '';
        if (total[1].length > 2) {
           total[3] = total[1].substr(2,1) == '0' ? '零' : total[1].substr(2,1);
               total[3] = total[3] == '2' ? '二' : total[3];
        }
}
$('.pay-total').attr({
        'role':'text',
        'aria-label':total[0] + '點' + total[2] + ' ' + total[3] + '元'
});

 

參考

Web 可訪問性與無障礙最佳實踐

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM