技術筆記|無障礙開發之螢幕閱讀器

8y Choice
13 min readJul 20, 2023

--

無障礙 AA 標章申請過了!!

上一篇分享了無障礙網站的鍵盤事件開發筆記,這一篇來聊聊無障礙網站的另一個好朋友:螢幕閱讀器

想像無法看到畫面,必須依靠聲音來認識一個網頁,這就是螢幕閱讀器在做的事

技術筆記|無障礙開發之螢幕閱讀器
想像無法看到畫面,必須依靠聲音來認識一個網頁

無障礙網站,廣泛的定義,是要各種使用者都能順利使用網站,像是

  • 視障的人,可以用聽的來理解並操作網頁
  • 色盲、色弱的人,不會因為網頁的用色,造成無法辨識內容的狀況
  • 手無法握著滑鼠的人,可以完全用鍵盤操作網頁

其他更多說明,可以參考 網站無障礙規範

想了解更多無障礙開網頁設計或發的注意事項,可以參考這篇

資訊傳遞

如何讓你的網站資訊被精準傳遞?

你會如何描述下面這張圖要傳達的資訊?

如何讓你的網站資訊被精準傳遞?
如何讓你的網站資訊被精準傳遞?

說明一:這張圖片在描述寫一篇部落格的流程,從圖片左上方開始是決定部落格的主題,箭頭延伸到左下方,是列出大綱,箭頭往中間延伸是內容構思 ….,箭頭到右上方,也就是最後一個步驟,是發表文章

說明二:這張圖片在描述寫一篇部落格的流程,有五個步驟,步驟依序為決定主題、列出大綱、內容構思…最後一步是發表文章

以上二種圖片說明,在看不到圖片、用聽的 情況下,哪一段比較容易理解?

對於資訊傳遞,開發者要思考的是怎樣的說明,能夠把資訊正確傳達,而不是單純把眼睛看到的念出來

雖然描述一的內容就 ”圖片描述” 的角度來說也是正確,但對於圖片意義的傳遞,卻多了許多不必要的資訊,像是左上、右下、箭頭等,對於資訊的理解並沒有正面幫助( 整段念完也多浪費了 10 秒的青春XD)

如何讓網站被念出來

我們的使用者,有的是用眼睛在閱讀網站、有的用耳朵在理解

以下項目,我們來思考一下是給誰的資訊

  1. 按鈕或連結,滑鼠滑上去時,會變顏色、或出現小手手
  2. 確認跟取消的按鈕,用不同顏色來強調
  3. 裝飾用圖片
  4. 流程圖再加上詳細說明

前二點都是很常見的網頁設計

確認按鈕通常比較醒目,暗示你可以大膽的按下去,而滑鼠經過可以被點擊的東西時,做特殊效果,則是為了提升使用者體驗

裝飾用圖片更不用說,“這是一張超萌超可愛的貓貓照,看到會覺得人生被療癒,但對不起你看不到”

這是一張超萌超可愛的貓貓照

對於看不到的使用者,最好連念出來都避免,以免增加使用網站的負擔

而流程圖的詳細說明,乍看之下很莫名其妙,因為我看圖就可以理解了,為什麼要放那些文字?

有趣的地方來了

如果你是靠圖片理解的,那看不到的人,該如何理解這段內容?

勢必得把圖片轉成可念出來的資訊吧!

但對於看得到的使用者(或是網頁設計師)來說,那段文字既多餘又礙眼

無障礙網頁開發和設計時,先思考哪些東西,要讓誰“看見”

無障礙網頁開發和設計時,先思考哪些東西,要讓誰”看見”
Photo by Balázs Kétyi on Unsplash

可是不可視

只讓眼睛看到

物件加上 arir-hidden='true'

最常見的是裝飾用圖片或 icon。讓眼睛看到,但要對螢幕閱讀器隱藏,降低視障者的負擔

<img src='圖片連結' arir-hidden='true'>

聽得到,看不到

只讓螢幕閱讀器看到,可以用 CSS 來處理

.sr-only {
clip: rect(1px, 1px, 1px, 1px);
// clip-path: inset(50%); // 會讓 focus 時看不到
width: 1px;
height: 1px;
padding: 1rem;
margin: -1px;
overflow: hidden;
border: 0;
position: absolute;
}

.sr-only-focusable:focus {
position: absolute !important;
width: auto !important;
height: auto !important;
clip: initial;
margin: inherit;
padding: inherit;
border: initial;
background-color: #004477;
color: #fff;
z-index: 999;
}

a.sr-only {
position: absolute!important;
padding: 2rem;
background-color: #2b358c;
color: #fff;
top: 0;
left: 0;
z-index: 999;
}

要特別注意的是,眼睛看不到的東西,有些需要在 鍵盤操作 focus 時,可以呈現出來

網路上找到的一些 sr-only 寫法,讓我在第二次送審時,小摔了一跤

無障礙網頁必備的導盲磚、一進入頁面的 “跳到主要內容區”,經常屬於看不到的元素

當時開心地加上了網路大神的推薦用法,沒發現有些本來 focus 會出現的東西,竟然被消失了

第二行的註解,就是當時發現並修正的地方

大家都不許看

沒有佔位空間 display:none ,有佔位空間 visibility:hidden

可以用在 RWD 時

Accessibility Tree

如何知道目前寫的東西會不會被螢幕閱讀器唸出來?(或是成功隱藏)

Accessibility Tree 就是拿來確認的小幫手,他是無障礙檢視工具看到的網頁樹狀結構,我將他理解成 “針對無障礙網頁的 DOM tree”

可以從我們最熟悉的網頁工具人F12 aka Chrome DevTool 查看

步驟一、開啟 Accessibility 檢視模式

  1. 在 Element 模式,點右邊三個點點
  2. 選擇 Accessibility
開啟 Accessibility 檢視模式
查看Accessibility Tree | 1. 開啟 Accessibility 檢視模式

步驟二、切換並重新整理 DevTool

  1. 勾選 “Enable full-page accessibility”
  2. 點擊 “Reload DevTool”,以重新整理 DevTool
查看Accessibility Tree | 2. 切換並重新整理 DevTool
查看Accessibility Tree | 2. 切換並重新整理 DevTool

步驟三、查看 Accessibility Tree

查看Accessibility Tree
查看Accessibility Tree

開發筆記

圖片<img> 與 icon

要有 alt, 是圖片描述,可以口語化,清楚易懂為主

有意義的 icon 需要替代文字,像是:警告、成功、錯誤等。在 icon 加上 aria-label=”錯誤、查看密碼、失敗...等”

裝飾性的 icon 或圖片加上 aria-hidden='true' ,好讓螢幕閱讀器直接忽略

連結 <a>

要有 title,用來提供連結的附加資訊。

螢幕閱讀器會念出 title 的內容,所以務必提供有意義和描述性的內容。

<a href="https://www.example.com" title="安安你好,點擊前往關於我的頁面">
關於我
</a>

按鈕 <button>

<button> 如果不在 <form> 裡,要加上 type = ‘button’,不然會觸發預設的 submit

文章看更多的 button 的加上 aria-label='看更多某某文章的內容'

<button aria-label='關閉'> X </button> 讓使用者知道某個顯示為”X”元件實際上有關閉的動作

aria-label='看更多零基礎轉職文章的內容' 讓使用者知道那個文字為”看更多”的按鈕,可以連結去看那篇叫做”零基礎轉職”的文章

按鈕加上清楚說明,並不影響網頁畫面

無障礙網站開發筆記
無障礙網站開發筆記-按鈕說明
  • 左:使用者只能得知按鈕上顯示的文字為“資料類型”,但不知道實際按下按鈕後會發生什麼事
  • 右:使用者可以預先知道按下去會開啟其他視窗,顯示內容為資料類型的清單

程式碼:91 行、在按鈕元件加上說明用的屬性

無障礙網站開發 | 在按鈕元件加上說明用的屬性
無障礙網站開發 | 在按鈕元件加上說明用的屬性

表格 <table>

加上摘要:大概描述表格的說明文字

方法一:`<caption>` 放在 `<table>` 裡的第一個元件

  • 表格加上說明給螢幕閱讀器的使用者,對一般使用者隱藏
  • 可用 Accessibility Tree 確認
<table class="spec-table">
<caption class="sr-only">
此表格列出每一種數據類型的量測項目,並提供每一個量測項目的單位、
是否為必填以及填寫範例等資訊。
</caption>
...
</table>

方法二:在 table附近加其他元件

`<p>` , `<span id=”aaa”>` 都可以,定義id,`<table aria-describedby=“aaa”>` 螢幕閱讀器就會讀取對應 id 的那個元件的內容,來當作表格的說明

表單 <form>

所有欄位都要加上 `aria-placeholder`

<el-form-item 
:label="$t('accountMenagement.email')"
prop="email"
>
<el-input
v-model="registerConsumerForm.email"
autocomplete="off"
:aria-placeholder="$t('Register.placeholderEmail')" // 這行
:placeholder="$t('Register.placeholderEmail')"
/>

用 element-ui 的 `<input type= “textarea” />` 時,會讀不到 label。可在 el-form-item 上綁定 id,再用 `aria-labelledby` 去讀

<el-form-item
id="descripUsageLabel" // 綁定 id
:label="$t('Register.placeholderDescripUsage')"
prop="suggestion"
>
<el-input
v-model="registerConsumerForm.suggestion"
aria-placeholder="$t('Register.placeholderEmail')"
aria-labelledby="descripUsageLabel" // 指向對應 id 的內容文字
type="textarea"
/>

主選單&側邊選單

aria-label='header-nav' 如果一個網頁架構上有好幾個 <nav>,螢幕閱讀器會告訴使用者這是上面的主選單

aria-label='footer-nav' 如果一個網頁架構上有好幾個 <nav>,螢幕閱讀器會告訴使用者這是底部的主選單

aria-label='social-media-nav' 如果一個網頁架構上有好幾個 <nav>,螢幕閱讀器會告訴使用者這選單裡都是放社群連結

role

role 會改變在 Accessibility Tree 上的顯示內容,通常不影響網頁外觀、互動、或預設的功能。

舉例來說:<ul role=”menu”> 回首頁 </ul> ,在 Accessibility Tree 上就不會看到 ul :回首頁,而會直接看到 menu :回首頁

(但這是個爛例子,請不要這樣用,不然裡面的 li 在Accessibility Tree 上,沒被包在 ul 裡會報錯)

常見 role

alert, button, dialog, gridcell, group, tab, tablist, tabpanel

aria-hidden 讓螢幕閱讀器的使用者,忽略畫面裡的東西

<a> <router-link> 不能包在 <button> 裡面,標籤太多層會造成螢幕閱讀器的困擾

其他補充

aria-labelledby='close' 這邊的說明就會是'關閉視窗' <div id="close"> 關閉視窗 </div> , aria-labelledby 的值可以放多個 id, 用空白隔開

aria-labelledbyaria-label 不能同時使用,只會讀到 labelledby (權重較高)

aria-labelledby 放簡要敘述,aria-discribedby 放詳細的說明

<button aria-pressed='false'> 暫停 </button> 按鈕目前沒被按下去,所以還在播放

結語

無障礙網頁跟螢幕閱讀器相關的部分,掌握一個重點

如何讓你的網站被 “說” 出來

很多 HTML 的原生屬性、以前覺得寫不寫都沒差的東西,在跟螢幕閱讀器交朋友時忽然理解他們的價值

螢幕閱讀器除了是無障礙網站的 BFF,同時能被他正確辨識的網站,網站 SEO 也會比較好

想想需要使用螢幕閱讀器的人,日常生活中勢必面對許多我們意想不到的困擾,他們要理解網頁已經夠辛苦了,身為開發人員的我們,就盡力分擔、讓他們輕鬆一點吧!

謝謝您的閱讀,如有任何疑問或想要分享您的經驗也歡迎留言,期待與您進一步交流!

如果喜歡我的文章,可以拍拍手讓我知道,更歡迎你追蹤並持續關注更多的分享。
想轉職工程師、對養成班有興趣、或對前端工程師有興趣的朋友們敬請期待 ~
我們下篇文章見!

你可能有興趣的其他文章

--

--

8y Choice

前端工程師 | 求職 | 轉職 | 學習成長 | 超主觀論點