iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 16
0

這系列無障礙的鐵人賽文章,實踐的內容主要是根據 W3C:WAI-ARIA 的實踐,從設計模式及組件(Design Patterns and Widgets)裡面挑選最想嘗試的,如果有朋友想瞭解全部 Widget 該怎麼實作及其規範,歡迎自行爬規範內容,也許我們可以討論一下;若以下文章內容理解有任何錯誤,請多指教~


選單按鈕 Menu Button(打開文件

3.16 Menu Button
A menu button is a button that opens a menu. It is often styled as a typical push button with a downward pointing arrow or triangle to hint that activating the button will display a menu.

前篇的「真・button——按鈕的世界比你想像複雜,別再用 div 刻假按鈕了!」主要介紹了:

  • 使用 <div><button> 製作按鈕的差異。
  • 介紹 WAI-ARIA 除了按鈕 button 被觸發的基本行為外,按鈕類型支援 Toggle Button 與 Menu Button。前篇就是介紹一般的按鈕與需要切換狀態的 Toggle Button。

想再複習的請點前篇文章,今天想介紹按鈕之於漢堡選單的應用,也就是 Menu Button!


漢堡選單 The Hamburger Menu

(圖片來源:UXPlanet

如上圖是三條槓或多條槓的呈現,現代應用程式因為導覽列放置的超連結通常都是三到五個起跳,在行動裝置有較小的版面狀況下,常會透過漢堡選單的視覺,固定覆蓋在畫面最上方,引導讓使用者那個位置可以點選,裡面放著網站的導覽超連結。

這裡就不探討漢堡選單的利弊,我們可以知道的是目前大多數使用者的使用習慣已經受應用程式介面影響,當他需要拜訪其他頁面時,直覺會想點擊漢堡選單到達目的地。


鍵盤的可訪問性

按鈕 Menu Button

  • Enter 或 Space
    • 能打開選單(Menu),並將焦點放在選單的第一個選項(Menu Item)
  • (選擇性)方向鍵 ,可依選項的順序操作焦點。
  • 選單開啟後,針對的鍵盤操作定義在 Menu or Menu bar (這也是 Widgets 之一)。

選單 Menu

內容太多了,涉略巢狀的選單行為,請點擊文件查看更多鍵盤操作的說明,這裡有 Element UI 團隊整理的簡中版本。

也許日後找機會整理,做成圖片說明比較合適!


Roles、States、Properties

按鈕 Menu Button

  • 按鈕的角色是 button,如果不是原生 <button>,應該要加上 role="button"
  • 為按鈕加上 aria-haspopup 屬性,值為 true 或是 menu,表示按鈕將啟動一個視窗,屬性說明點這裡
  • 如果選單開啟就幫按鈕加上 aria-expanded 屬性,值設為 true。選單關閉時,建議直接隱藏 aria-expanded屬性設定,如果選單在關閉的狀態時,你已經為按鈕加上 aria-expanded屬性,不打算透過 JavaScript 移除屬性,那麼就把值設為 false吧。
  • (選擇性)可以為按鈕定義關聯它將開啟的選單 id,方式是為按鈕加上 aria-control="Menu角色元素的id"

選單 Menu

  • 透過按鈕開啟的選單,必須具有 menu 的角色設定。
  • 內容太多了,涉略巢狀的選單行為,請點擊文件查看更多鍵盤操作的說明。

實踐開始囉!

今天想引用 Bootstrap v4.3 的 Navbar 來看看,CSS 知名框架是怎麼處理 A11Y 的呢?一起檢視 Menu Button 的最佳建議是不是都實現了呢?

希望能做到:

  • [x] 支援螢幕閱讀器
  • [x] 可使用鍵盤操作

原始 HTML,官方文件

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">我們來看 Bootstrap 4.3 Navbar 的可訪問性</a>
	<!-- 1. 按鈕角色、3. 定義按鈕能觸發選單、4. 建立選單與按鈕之間的關聯 -->
	<!-- a. 注意細節: aria-label -->
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
	<!-- 5. 沒有選單角色 -->
  <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
    <div class="navbar-nav">
			<!-- b. 注意細節: .sr-only -->
      <a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
      <a class="nav-item nav-link" href="#">Features</a>
      <a class="nav-item nav-link" href="#">Pricing</a>
			<!-- c. 注意細節: disabled 的處理 -->
      <a class="nav-item nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
    </div>
  </div>
</nav>

檢查 Roles, States, and Properties:

  1. [ V ] 按鈕角色:打開選單的「按鈕」的角色是 button
  2. [ X ] 定義按鈕能觸發選單:為按鈕加上 aria-haspopup 屬性,值為 true 或是 menu
  3. [ V ] 選單是否展開:如果選單開啟就幫按鈕加上 aria-expanded 屬性,值設為 true,反之亦然。
  4. [ V ](選擇性)建立選單與按鈕之間的關聯:可以為按鈕定義關聯它將開啟的選單 id,方式是為按鈕加上 aria-control="Menu角色元素的id"

檢查 Menu:

  1. [ X ] 選單角色:透過按鈕開啟的選單,必須具有 menu 的角色設定。註:此範例不是巢狀選單, menu 角色其餘的行為這裡不檢查。

Bootstrap 對於沒加上 role="menu" 的說明:
The WAI ARIA standard defines an actual role="menu" widget, but this is specific to application-like menus which trigger actions or functions. ARIA menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus. Bootstrap’s dropdowns, on the other hand, are designed to be generic and applicable to a variety of situations and markup structures. For instance, it is possible to create dropdowns that contain additional inputs and form controls, such as search fields or login forms. For this reason, Bootstrap does not expect (nor automatically add) any of the role and aria- attributes required for true ARIA menus. Authors will have to include these more specific attributes themselves.

注意細節!

a. 按鈕本身有加上 aria-label="Toggle navigation"在 Accessibility Tree 上為自己補充名稱,因為按鈕的內容是「漢堡圖示」 <span class="navbar-toggler-icon"></span>,所以一定要加上 aria-label 唷!

b. .sr-only 這個樣式是要給螢幕閱讀器讀取的,它消失在瀏覽器的畫面上,卻不是真正的消失。

真正消失是指使用 display: none 或是 visibility: hidden 或是 HTML5 的 hidden 屬性。

不是真正的消失指的作法如下:

<a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a>

/* _screen-reader.scss */
.sr-only {
	position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

我可以想到的另外一種做法是:在超連結上使用 aria-current="page",表示目前是當前頁面。

<a class="nav-item nav-link active" href="#" aria-current="page">Home</a>

c. disabled 的處理:

  • tabindex="-1" ,螢幕閱讀器無法 focus 被 disabled 的元素。
  • aria-disabled="true" ,螢幕閱讀器會知道這是一個 disabled的超連結。

改良的作法:把上面的 X 補上囉!

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">我們來看 Bootstrap 4.3 Navbar 的可訪問性</a>
	<!-- 1. 按鈕角色、3. 定義按鈕能觸發選單、4. 建立選單與按鈕之間的關聯、加上 aria-haspopup -->
	<!-- a. 注意細節: aria-label -->
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation" aria-haspopup="menu">
    <span class="navbar-toggler-icon"></span>
  </button>
	<!-- 5. 選單角色 -->
  <div class="collapse navbar-collapse" id="navbarNavAltMarkup" role="menu">
    <div class="navbar-nav">
			<!-- b. 注意細節: 移除 .sr-only 改成 aria-current -->
      <a class="nav-item nav-link active" href="#" aria-current="page">Home</a>
      <a class="nav-item nav-link" href="#">Features</a>
      <a class="nav-item nav-link" href="#">Pricing</a>
			<!-- c. 注意細節: disabled 的處理 -->
      <a class="nav-item nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
    </div>
  </div>
</nav>

最後,這裡還是有為選單加上 role="menu",因為我看 menu 這個角色的官方定義沒有像 BS 說的只能容納 checkbox、radio 等元件,而且在這個範例中,它就是我的選單呀~所以在此例補充語義會比較完善。

codepen 在這裏,快來使用鍵盤操作看看吧!還想看更多範例嗎?那就參考 WAI-ARIA Practice 1.1 的選單範例吧。


Reference


上一篇
實作無障礙網頁功能:真・button —— 按鈕的世界比你想像複雜,別再用 div 刻假按鈕了!
下一篇
實作無障礙網頁功能:超連結還能怎樣無障礙呢?
系列文
實踐無障礙網頁設計(Web Accessibility)30

1 則留言

0
Gary
iT邦新手 1 級 ‧ 2019-10-02 22:43:45

寫的真好!/images/emoticon/emoticon74.gif

謝謝你的鼓勵Q____Q

我要留言

立即登入留言