aboutsummaryrefslogtreecommitdiff
path: root/files/zh-tw/learn/accessibility/wai-aria_basics/index.html
blob: 2dda380c7c4cd9e01532402baf37fcf300c55f3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
---
title: WAI-ARIA基礎
slug: Learn/Accessibility/WAI-ARIA_basics
translation_of: Learn/Accessibility/WAI-ARIA_basics
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}</div>

<p class="summary">接續之前的文章,有時在涉及非語意HTML與動態 JavaScript更新的內容製作複雜的UI控制措施將是個難題。WAI-ARIA即是一個能藉由添加進一步的語意幫助處理這種問題的技術 ,讓瀏覽器與輔助科技可以辨識及用以讓使用者知道發生甚麼事情。這裡我們將展示如何以基本水準的運用來增進無障礙使用。</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">先決條件:</th>
   <td>基本電腦技能、基本瞭解HTML, CSS與JavaScript、瞭解本課程先前文章。</td>
  </tr>
  <tr>
   <th scope="row">目標:</th>
   <td>能熟悉WAI-ARIA,以及在必要時如何用於提供有用的附加語意強化無障礙。</td>
  </tr>
 </tbody>
</table>

<h2 id="甚麼是WAI-ARIA">甚麼是WAI-ARIA?</h2>

<p>開始瞭解甚麼是WAI-ARIA,以及它可為我們做些甚麼。</p>

<h3 id="一個全新問題集"><strong>一個全新問題集</strong></h3>

<p>當網站應用程式開始更複雜與動態,新的無障礙特性與問題集就開始出現。</p>

<p>例如,HTML5 導入許多語意的元素來定義一般頁面的特性({{htmlelement("nav")}}, {{htmlelement("footer")}}等) 在沒有這些可用之前,開發者僅簡單使用{{htmlelement("div")}}搭配IDs或classes,如&lt;div class="nav"&gt;,但這些是有問題的,因為沒有很簡單的方法可程式化地容易找到特定的頁面特性如主要導覽功能。</p>

<p>起初的解決方案是在頁面的頂端添加一個或更多隱藏的連結去連結到導覽功能(或其他任何的功能),例如:</p>

<pre class="brush: html">&lt;a href="#hidden" class="hidden"&gt;Skip to navigation&lt;/a&gt;</pre>

<p>但這仍然不是非常精確,並且僅能使用於螢幕報讀器從頁面頂端閱讀下來的時候。</p>

<p>如同另一個例子,應用程式開始具有複雜的控制措施如日期選取器提供選擇日期,內容滑塊提供選取內容值等。HTML5提供特定的輸入型態來呈現這些控制措施:</p>

<pre class="brush: html">&lt;input type="date"&gt;
&lt;input type="range"&gt;</pre>

<p>這些在跨瀏覽器之間沒有全面性支援,而且也非常困難去為他們指定樣式,而使他們與網站設計整合時不是很好用。因此,開發者時常依賴JavaScript資源庫來產生這些一系列內嵌的控制措施 {{htmlelement("div")}}或具有classnames的表格元素,透過CSS指定樣式與使用JavaScript控制。</p>

<p>這個的問題是視覺上可以運作,但螢幕報讀器則一點也無法理解它們是甚麼,以及它們的使用者僅被告知他們可以看到一堆沒有語意的元素來描述它們的含意。</p>

<h3 id="進入WAI-ARIA">進入WAI-ARIA</h3>

<p><a href="https://www.w3.org/TR/wai-aria-1.1/">WAI-ARIA</a> 是一個由W3C編撰的規格,定義一套額外的HTML屬性能用於元素上提供額外的語意及改善可及性,當元素缺乏這些條件時可適用。本規格定義三個主要的特點:</p>

<ul>
 <li><strong>Roles</strong> — 這些角色用以定義元素是甚麼或做甚麼事。在這些當中許多被稱為地標角色,大部分重複了HTML5結構化元素的語意值如<code>role="navigation"</code> ({{htmlelement("nav")}}) or <code>role="complementary"</code> ({{htmlelement("aside")}}), 但也有其他描述不同的頁面結構者,如<code>role="banner"</code>, <code>role="search"</code>, <code>role="tabgroup"</code>, <code>role="tab"</code>等常見於使用者介面中。</li>
 <li><strong>Properties</strong> — 這些用以定義元素的屬性,可用來賦予元素額外的意義或語意。舉例,<code>aria-required="true"</code>指定一個表單輸入必須填寫才有效,而<code>aria-labelledby="label"</code>讓你可以在一個元素上置放一個ID,當該頁面上任何內容設定標籤後而引用它,頁面包含多個元素而不可能使用<code>&lt;label for="input"&gt;</code>。舉例,你可使用<code>aria-labelledby</code>指定一個鍵盤鍵描述包含在一個{{htmlelement("div")}}之中是多個表格儲存格的標籤,或者你可使用它做為圖片alt文字的替代方案 — 指定頁面上現有的資訊做為圖片的alt文字,而非將它重複放在<code>alt</code>屬性之內. 範例可參考<a href="/en-US/docs/Learn/Accessibility/HTML?document_saved=true#Text_alternatives">Text alternatives</a></li>
 <li><strong>States</strong> — 定義目前元素狀態的特殊屬性,例如 <code>aria-disabled="true"</code>,是對螢幕報讀器指定表單輸入目前是停用的狀態。狀態不同於屬性,在於屬性在應用程序整個生命週期中不會改變,而狀態通常會透過 JavaScript程式化改變。</li>
</ul>

<p>有關WAI-ARIA屬性的重要觀點是他們不會影響網頁的任何內容,除了透過瀏覽器無障礙API揭露資訊之外(螢幕報讀器即從中獲得資訊)。儘管WAI-ARIA屬性對CSS選擇元素很有用,但不會影響網頁結構、DOM等。</p>

<div class="note">
<p><strong>注意:</strong>你可以在WAI-ARIA規格中找到所有ARIA的角色及其用法的很有用清單,請參見 <a href="https://www.w3.org/TR/wai-aria-1.1/#role_definitions">Definition of Roles</a>連結以獲得更進一步的資訊。</p>

<p>本規格也涵括所有屬性與狀態的清單,請參見 <a href="https://www.w3.org/TR/wai-aria-1.1/#state_prop_def">Definitions of States and Properties (all aria-* attributes)</a>連結以獲得更進一步的資訊。</p>
</div>

<h3 id="哪裡支援WAI-ARIA?">哪裡支援WAI-ARIA?</h3>

<p>這不是一個容易回答的問題。要難找到一個決定性的資源來陳述何者是支援WAI-ARIA的特點以及在何處,因為:</p>

<ol>
 <li>在WAI-ARIA規格中有很多特點。</li>
 <li>要考量作業系統、瀏覽器與螢幕報讀器的許多組合。</li>
</ol>

<p>最後一點是關鍵—首先要使用螢幕報讀器,你的作業系統必須執行具有必要的無障礙API的瀏覽器去揭露螢幕報讀器必須去完成工作的資訊。大部分主流的作業系統有1個或2個瀏覽器可供螢幕報讀器使用。Paciello Group一則最近的文章提供這些數據—請參見 <a href="https://www.paciellogroup.com/blog/2014/10/rough-guide-browsers-operating-systems-and-screen-reader-support-updated/">Rough Guide: browsers, operating systems and screen reader support updated</a></p>

<p>接著,你必須擔心瀏覽器是否支援ARIA特徵並透過其API揭露,同時螢幕報讀器是否辨識該資訊並以可用的方式向使用者呈現的問題。</p>

<ol>
 <li>瀏覽器支援一般相當好—在撰文當下, <a href="http://caniuse.com/#feat=wai-aria">caniuse.com</a>表示全球瀏覽器對WAI-ARIA的支援率大約為88%。</li>
 <li>螢幕報讀器對ARIA特徵的支援沒有相當於此水平,但大部分主流的螢幕報讀器是有達到此水平。你可查閱Powermapper的 <a href="http://www.powermapper.com/tests/screen-readers/aria/">WAI-ARIA Screen reader compatibility</a>這篇文章了解支援的水平。</li>
</ol>

<p>在本文中,我們未試圖涵蓋每一個WAI-ARIA特徵及其確切的支援細節。相反地,我們將涵蓋最關鍵的WAI-ARIA特徵讓你知道;如果我們沒有提到任何支援細節,你可認定該特徵得到很好的支援。我們會明確地提到這個例外情況。</p>

<div class="note">
<p><strong>注意</strong>:某些JavaScript儲存庫支援WAI-ARIA,亦即當他們產生UI特徵如複雜的表單控制措施,他們添加ARIA屬性來增進這些特徵的無障礙。如果你在尋找第三方的JavaScript解決方案來快速的開發UI,你應該謹慎地考量其UI插件的無障礙作為你決定使用的重要因素。jQuery UI(參見<a href="https://jqueryui.com/about/#deep-accessibility-support">About jQuery UI: Deep accessibility support</a>)、 <a href="https://www.sencha.com/products/extjs/">ExtJS</a>與 <a href="https://dojotoolkit.org/reference-guide/1.10/dijit/a11y/statement.html">Dojo/Dijit</a>是良好範例。</p>
</div>

<h3 id="何時應該使用WAI-ARIA"><strong>何時應該使用WAI-ARIA?</strong></h3>

<p>我們討論了促使WAI-ARIA早期建立的一些問題,但基本上WAI-ARIA在4個主要領域很有用:</p>

<ol>
 <li><strong>路標/地標:</strong>ARIA的角色屬性值可作為地標,不是複製HTML5元素的語意(如{{htmlelement("nav")}}),就是超越HTML5語意而對不同的功能區域提供路標,如搜尋、頁籤群組、頁籤、清單框等。</li>
 <li><strong>動態內容更新:</strong>螢幕報讀器往往難以報讀不斷改變的內容;當某個內容區域更新時,我們可以使用aria-live通知螢幕報讀器的使用者,例如透過 <a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a><a href="/en-US/docs/Web/API/Document_Object_Model">DOM APIs</a></li>
 <li><strong>增強鍵盤無障礙</strong>:內建的HTML元素具有原生的鍵盤無障礙;當其他元素伴隨使用JavaScript模擬相似的互動時,鍵盤無障礙操作與螢幕報讀器報讀會遭遇問題。如果這是不可避免的,WAI-ARIA提供讓其他元素獲得焦點的一種方法(使用 <code>tabindex</code>)。</li>
 <li><strong>非語意控制措施的無障礙</strong>:當一系列巢狀的<code>&lt;div&gt;</code>搭配CSS/JavaScript用於創建一個複雜的UI特徵,或者一個透過JavaScript大幅增強/改變的原生控制措施,無障礙會遭遇到困難—如果沒有語意或其他線索,螢幕報讀器使用者將發覺難以理解該特徵的作用。在這種情況下,ARIA可以幫助提供缺失的部分使用如按鈕、清單框或頁籤群組等角色組合,以及aria-required 或aria-posinset等屬性對功能性提供進一步的線索。</li>
</ol>

<p>記住一件事 — <strong>僅在必需時才使用WAI-ARIA! </strong>理想情況下,你應該總是使用<a>原生HTML特徵</a>提供螢幕報讀器所需要的語意來告訴其使用者接下來將發生甚麼事情。有時候這是不可能的情形,不是因為你受限於控制該程式碼,就是因為你創建一些複雜而無法用簡易的HTML元素來開發。在這種情況下,WAI-ARIA可作為有價值的無障礙增強工作。</p>

<p>再說一次,只有需要的時候才使用它!</p>

<div class="note">
<p><strong>注意</strong>: 請確保有各類實際的使用者來測試你的網站 — 非身障者、使用螢幕報讀器者、使用鍵盤導覽者等。他們將比你更能了解它運作的效果。</p>
</div>

<h2 id="實作WAI-ARIA開發">實作WAI-ARIA開發</h2>

<p>在下一個章節我們將更仔細地看看這4個領域,並附帶實際的範例。在繼續之前,你應該將備妥螢幕報讀器測試設置,以便在過程中你可以測試這些範例。</p>

<p>更多資訊請參見<a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Screenreaders">螢幕報讀器測試</a>章節。</p>

<h3 id="路標地標"><strong>路標/地標</strong></h3>

<p>WAI-ARIA添加<a href="https://www.w3.org/TR/wai-aria-1.1/#role_definitions">角色屬性</a>給瀏覽器,讓你可以在必要時添加額外的語意值到你網站上的元素。這第一個主要的領域在為螢幕報讀器提供資訊方面非常有用,讓螢幕報讀器的使用者可以找到常見的頁面元素。我們來看個範例 — <a href="https://github.com/mdn/learning-area/tree/master/accessibility/aria/website-no-roles">網站-無-角色</a>範例(<a href="http://mdn.github.io/learning-area/accessibility/aria/website-no-roles/">看實際頁面</a>)有以下的結構:</p>

<pre class="brush: html">&lt;header&gt;
  &lt;h1&gt;...&lt;/h1&gt;
  &lt;nav&gt;
    &lt;ul&gt;...&lt;/ul&gt;
    &lt;form&gt;
      &lt;!-- search form  --&gt;
    &lt;/form&gt;
  &lt;/nav&gt;
&lt;/header&gt;

&lt;main&gt;
  &lt;article&gt;...&lt;/article&gt;
  &lt;aside&gt;...&lt;/aside&gt;
&lt;/main&gt;

&lt;footer&gt;...&lt;/footer&gt;</pre>

<p>若你嘗試在現代瀏覽器中使用螢幕報讀器來測試此範例,你將可以獲得一些有用的資訊。例如,VoiceOver給你以下的資訊:</p>

<ul>
 <li><code>&lt;header&gt;</code> 元素上— "橫幅,2個項目"(含有一個標題與 <code>&lt;nav&gt;</code>)。</li>
 <li><code>&lt;nav&gt;</code> 元素上—"導航列 2個項目" (含有一個清單與一個表單)。</li>
 <li><code>&lt;main&gt;</code> 元素上—"主要內容 2個項目" (含有一則文章與一個附帶內容)。</li>
 <li><code>&lt;aside&gt;</code> 元素上—"補充 2個項目" (含有一個標題與一個清單)。</li>
 <li>在搜尋表單輸入—"搜尋查詢,插入文字開始處"。</li>
 <li><code>&lt;footer&gt;</code> 元素上—"頁尾1個項目"。</li>
</ul>

<p>如果你到VoiceOver地標選單(使用VoiceOver主鍵+ U,然後使用游標鍵循環整個選單選項),你會看到大部分元素被列的很好,因此可以很快地訪問他們。</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/14420/landmarks-list.png" style="display: block; margin: 0 auto;"></p>

<p>然而,這裡我們可以做得更好,搜尋表單是一個人們想要找到的很重要的地標,但是它並沒有列在地標選項之中或者被視為顯著的地標,除了在實際輸入而被召喚作為搜尋輸入之外(<code>&lt;input type="search"&gt;</code>)。另外,有些舊的瀏覽器(大部分是指IE8)無法辨識HTML5元素的語意。</p>

<p>讓我們使用一些ARIA特徵來改善它。首先,我們將添加一些角色屬性到我們的HTML結構。你可以試著複製我們原始的檔案(參見<a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/website-no-roles/index.html">index.html</a><a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/website-no-roles/style.css">style.css</a>),或者瀏覽我們的<a href="https://github.com/mdn/learning-area/tree/master/accessibility/aria/website-aria-roles">網站-aria-角色</a>範例(<a href="http://mdn.github.io/learning-area/accessibility/aria/website-aria-roles/">看實際頁面</a>),其結構如下:</p>

<pre class="brush: html">&lt;header&gt;
  &lt;h1&gt;...&lt;/h1&gt;
  &lt;nav role="navigation"&gt;
    &lt;ul&gt;...&lt;/ul&gt;
    &lt;form role="search"&gt;
      &lt;!-- search form  --&gt;
    &lt;/form&gt;
  &lt;/nav&gt;
&lt;/header&gt;

&lt;main&gt;
  &lt;article role="article"&gt;...&lt;/article&gt;
  &lt;aside role="complementary"&gt;...&lt;/aside&gt;
&lt;/main&gt;

&lt;footer&gt;...&lt;/footer&gt;</pre>

<p>在本範例中我們也將給你一個額外的特徵—{{htmlelement("input")}} 元素賦予 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-label">aria-label</a></code>屬性,藉由給予描述性的標籤讓螢幕報讀器可以報讀出來,即使我們沒有包含{{htmlelement("label")}}元素。像這種情況就非常有用—搜尋表單是一個非常常見、容易辨識的特徵,而添加視覺的標籤可能破壞頁面的設計。</p>

<pre class="brush: html">&lt;input type="search" name="q" placeholder="Search query" aria-label="Search through site content"&gt;</pre>

<p>現在如果我們使用VoiceOver來看這個範例,我們可以獲得一些改善:</p>

<ul>
 <li>召喚搜尋表單當作獨立的項目,無論是在瀏覽頁面,或在地標選項之中。</li>
 <li>當表單輸入凸顯時,將報讀出包含在<code>aria-label</code>屬性的標籤文字。</li>
</ul>

<p>除此之外,該網站對舊瀏覽器如IE8的使用者更可能無障礙;為了這個目的,包含ARIA角色是值得的。如果為了某些原因,你的網站僅使用 <code>&lt;div&gt;</code>建置,那麼肯定你應該包含ARIA角色來提供這些非常需要的語意!</p>

<p>當ARIA超越從HTML5所能獲得的語意時,搜尋表單的改進語意已經顯示實現的可能性。你將會在下面看到更多關於這些語意與ARIA屬性的能力,尤其在<a href="#非語意控制措施的無障礙">Accessibility of non-semantic controls</a>章節。現在,我們先來看看ARIA如何幫助動態內容更新。</p>

<h3 id="動態內容更新">動態內容更新</h3>

<p>從文本內容到附著於圖片的替代文字,其內容載入至DOM中可方便螢幕報讀器使用。因此,大部分使用文字內容的傳統靜態網站能輕易讓視覺障礙者無障礙使用。</p>

<p>問題在於現代網頁應用程式通常不只是靜態的文字—他們傾向有很多動態更新的內容,例如透過像<a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a>, <a href="/en-US/docs/Web/API/Fetch_API">Fetch</a>, 或<a href="/en-US/docs/Web/API/Document_Object_Model">DOM APIs</a>等機制更新的內容而不必重新載入全部的頁面。這些有時稱為即時區塊。</p>

<p>我們來看一個簡單的範例—請看 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/aria-no-live.html">aria-no-live.html</a> (<a href="http://mdn.github.io/learning-area/accessibility/aria/aria-no-live.html">看實際頁面</a>)。本範例中我們有簡單的隨機引言框:</p>

<pre class="brush: html">&lt;section&gt;
  &lt;h1&gt;Random quote&lt;/h1&gt;
  &lt;blockquote&gt;
    &lt;p&gt;&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/section&gt;</pre>

<p>我們的JavaScript透過含有一系列的隨機引言與其作者的 <code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> <code>載入一個</code>JSON檔案。一旦這些完成,我們就開始 <code><a href="/en-US/docs/Web/API/WindowTimers/setInterval">setInterval()</a></code> 迴圈每10秒載入新的隨機引言到引言框之中。</p>

<pre class="brush: js">var intervalID = window.setInterval(showQuote, 10000);</pre>

<p>這個運作正常,但對無障礙不是很好—此內容更新無法被螢幕報讀器所偵測,所以他們的使用者不知道發生甚麼事情。這是一個相當平凡的例子,但只要想像一下如果你正在創建一個有著大量不斷更新內容的複雜UI,如聊天室、一個策略型的遊戲UI、或者一個即時更新的購物車顯示窗—則將不可能以任何有效的方式使用該應用程式而沒有某種提醒使用者該更新內容的方法。</p>

<p>很幸運地WAI-ARIA提供一項有用的機制來提供這些警告—即<code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-live">aria-live</a></code> 屬性。將此屬性用在元素上可讓螢幕報讀器讀出更新的內容。報讀內容的緊急性決定於以下屬性值:</p>

<ul>
 <li><code>off:</code> 預設值,更新不應該通知。</li>
 <li><code>polite</code>: 更新應該只在使用者空閒時才通知。</li>
 <li><code>assertive</code>: 更新應盡快通知使用者。</li>
 <li><code>rude</code>: 更新應立即通知,即使打斷使用者。</li>
</ul>

<p>一般而言, <code>assertive</code> 設置足以讓你的更新內容在他們出現時依序地讀出,因此如果同時有多個事件改變,你將獲得所有的更新。只有對非常高優先順序的更新使用  <code>rude</code> 才能覆蓋其他所有的更新。</p>

<p>我們希望你複製 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/aria-no-live.html">aria-no-live.html</a> 與 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/quotes.json">quotes.json</a>,並更新 <code>&lt;section&gt;</code> 標籤如下所示:</p>

<pre class="brush: html">&lt;section aria-live="assertive"&gt;</pre>

<p>這將使螢幕報讀器在內容更新時讀出更新的內容。</p>

<div class="note">
<p><strong>注意</strong>: 如果你嘗試從 <code>XMLHttpRequest</code> 執行 <code>file://</code> URL<code></code>大部分的瀏覽器會拋出安全異常,例如你直接上傳該檔案到瀏覽器(透過雙擊滑鼠鍵等)。為了這項可以執行,你需要將檔案上傳到一個網站伺服器如<a href="/en-US/docs/Learn/Common_questions/Using_Github_pages"> GitHub</a>,或本機網站伺服器如 <a href="http://www.pythonforbeginners.com/modules-in-python/how-to-use-simplehttpserver/">Python's SimpleHTTPServer</a></p>
</div>

<p>這裡有一項額外的考量—只有文字更新才讀出。如果我們也總是讀出標題,那將很好,以讓使用者記住讀出的內容。為做到這樣,我們可以添加 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-atomic">aria-atomic</a></code> 屬性到這個部分,再次更新您的 <code>&lt;section&gt;</code> 標籤如下所示:</p>

<pre class="brush: html">&lt;section aria-live="assertive" aria-atomic="true"&gt;</pre>

<p><code>aria-atomic="true"</code>屬性告訴螢幕報讀器以一個原子單位方式讀出完整的元素內容,而不僅只讀出更新的部分。</p>

<div class="note">
<p><strong>注意</strong>:你可以查看完成的範例 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/aria-live.html">aria-live.html</a> (<a href="http://mdn.github.io/learning-area/accessibility/aria/aria-live.html">看實際頁面</a>)。</p>
</div>

<div class="note">
<p><strong>注意</strong>: <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-relevant">aria-relevant</a></code> 屬性在即時區塊更新時對於控制讀出甚麼內容也相當有用,例如你可以僅獲得讀出新增或移除的內容。</p>
</div>

<h3 id="增強鍵盤無障礙"><strong>增強鍵盤無障礙</strong></h3>

<p>如同在本模組其他章節所討論, HTML關於無障礙的關鍵優勢之一是內建鍵盤無障礙特徵如按鈕、表單控制措施及連結。一般而言,你可以使用tab鍵在控制措施之間移動,輸入(Enter)/返回(Return)鍵用來選擇或觸發控制措施,以及偶爾需要其他的控制措施(例如上下游標在 <code>&lt;select&gt;</code> 框中的選項間移動)。</p>

<p>然而,有時你最終必須撰寫不是使用非語意的元素如按鈕(或其他控制的型態),或者使用可獲焦點的控制措施用作非正確目的程式碼。你可能嘗試修正一些繼承來的不好的程式碼,或者你可能創建需要某些種類的複雜插件。</p>

<p>讓非焦點的程式碼可獲得焦點,WAI-ARIA使用一些新值擴展 <code>tabindex</code> 屬性:</p>

<ul>
 <li><code>tabindex="0"</code> —如上述,此值允許正常不被tab遊走到的元素變得可以tab遊走,這是<code>tabindex</code>最有用的值。</li>
 <li><code>tabindex="-1"</code> — 此允許正常不被tab遊走到的元素,可以程式化地獲得焦點,如透過JavaScript或作為連結的對象。</li>
</ul>

<p>我們更詳細討論這一點並在我們的HTML無障礙文章中展示典型的實作—請參見 <a href="/en-US/docs/Learn/Accessibility/HTML#Building_keyboard_accessibility_back_in">Building keyboard accessibility back in</a>.</p>

<h3 id="非語意控制措施的無障礙">非語意控制措施的無障礙</h3>

<p>本部份接續前一章節—當一系列巢狀的 <code>&lt;div&gt;</code>搭配CSS/JavaScript用於創建一個複雜的UI特徵,或者一個透過JavaScript大幅增強/改變的原生控制措施,不僅鍵盤無障礙會遭遇到困難,而且如果沒有語意或其他線索,螢幕報讀器使用者也會發覺難以理解該特徵的作用。在這種情況下,ARIA可以幫助提供缺失的語意。</p>

<h4 id="表單驗證與錯誤警告">表單驗證與錯誤警告</h4>

<p>首先,讓我們再看一次在我們的CSS與JavaScript無障礙文章中第一次看的表單範例(請閱讀 <a href="/en-US/docs/Learn/Accessibility/CSS_and_JavaScript#Keeping_it_unobtrusive">Keeping it unobtrusive</a>完整回顧)。在本章節文末我們展示當你試著送出表單而驗證錯誤時,出現我們包含一些在錯誤訊息框的ARIA屬性。</p>

<pre class="brush: html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>errors<span class="punctuation token">"</span></span> <span class="attr-name token">role</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>alert<span class="punctuation token">"</span></span> <span class="attr-name token">aria-relevant</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>all<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>ul</span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>ul</span><span class="punctuation token">&gt;</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span></code></pre>

<ul>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#alert">role="alert"</a></code> 自動地將其應用的該元素轉換為即時區塊,以利讀出它的改變;它也將語意地辨識其為警告訊息(重要時間/內容脈絡敏感資訊),而呈現以更好、更無障礙的方式向使用者傳遞警告(模態對話框如 <code><a href="/en-US/docs/Web/API/Window/alert">alert()</a></code> 具有許多無障礙的問題;請參見WebAIM的 <a href="http://webaim.org/techniques/javascript/other#popups">Popup Windows</a>)。</li>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-relevant">aria-relevant</a></code> 的all值指示螢幕報讀器當它任何改變時讀出錯誤清單的內容—例如當錯誤新增或移除時。這個很有用因為使用者會想知道留著的錯誤是甚麼,而不只有知道清單中甚麼是已經新增或移除。</li>
</ul>

<p>我們可進一步使用我們的ARIA,並提供更多的驗證協助。如何指出區塊是否需要在第一個位置,以及年齡的範圍應該多少?</p>

<ol>
 <li>在此,複製我們的 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/form-validation.html">form-validation.html</a> 與 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/css/validation.js">validation.js</a> 檔案,並將他們儲存在本機目錄。</li>
 <li>在文字編輯器開啟他們並且看一下該程式碼如何運作。</li>
 <li>首先,在開始的 <code>&lt;form&gt;</code> 標籤之上增加一個段落,如下所示,並且用星號標記兩個表單的 <code>&lt;label&gt;</code>。這是一般我們對有視力的使用者標記必要區塊的方法。
  <pre class="brush: html">&lt;p&gt;Fields marked with an asterisk (*) are required.&lt;/p&gt;</pre>
 </li>
 <li>這讓視覺有意義,但這對螢幕報讀器使用者不能輕易理解。很幸運地,WAI-ARIA提供 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-required">aria-required</a></code> 屬性以提示螢幕報讀器應告訴使用者需要填寫的表單輸入欄位。更新<code>&lt;input&gt;</code> 元素如下:
  <pre class="brush: html">&lt;input type="text" name="name" id="name" aria-required="true"&gt;

&lt;input type="number" name="age" id="age" aria-required="true"&gt;</pre>
 </li>
 <li>如果你現在儲存本範例並使用螢幕報讀器測試,你應該聽到這個內容 "Enter your name star, required, edit text"。</li>
 <li>如果我們給予螢幕報讀器使用者與視覺的使用者有關年齡的值應該是甚麼的概念,這樣也將會很有用。這個或許常以提示或在表單輸入區內預設文本的方式呈現。WAI-ARIA用包含 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-valuemin">aria-valuemin</a></code> 與 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-valuemax">aria-valuemax</a></code> 屬性來指定最小與最大值,但這些目前未受到很好的支持;比較受支持的特徵是 HTML5 <code>placeholder</code> 屬性,它在沒有輸入值的時間將含有的訊息顯示在輸入框,並能由許多螢幕報讀器讀出。更新你的數值輸入如下所示:
  <pre class="brush: html">&lt;input type="number" name="age" id="age" placeholder="Enter 1 to 150" aria-required="true"&gt;</pre>
 </li>
</ol>

<div class="note">
<p><strong>注意</strong>:你可以查看完成的範例 <a href="http://mdn.github.io/learning-area/accessibility/aria/form-validation-updated.html">form-validation-updated.html</a></p>
</div>

<p>除了傳統的 {{htmlelement("label")}} 元素之外,WAI-ARIA也能賦予一些進階的表單標籤技術。我們已經談論過使用 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-label">aria-label</a></code> 屬性在我們不希望標籤讓有視覺的使用者看見的地方來提供標籤(參見上述 <a href="#路標地標">路標/地標</a> 章節。如果你想要指定一個非<code>&lt;label&gt;</code> 元素當作標籤或具有相同標籤多重的表單輸入標籤,這裡有使用其他屬性如 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby">aria-labelledby</a></code> 的其他標籤技術,如果你想要其他的訊息與表單輸入關聯並且報讀出來,使用 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-describedby">aria-describedby</a></code>。更多細節請參見 <a href="http://webaim.org/techniques/forms/advanced">WebAIM's Advanced Form Labeling article</a><span class="subtitle"></span></p>

<p>還有許多其他有用的屬性與狀態,用來指出表單元素的狀態。例如,<span class="subtitle"> <code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-disabled">aria-disabled</a>="true"</code> </span>可用於指出表單區域是處於停用的狀態。許多瀏覽器只會跳過停用的表單區塊,並且甚至不會被螢幕報讀器讀出,但在某些情況下,他們可被感知,所以最好包含此屬性讓螢幕報讀器知道停用的輸入事實上即是停用的狀態。</p>

<p>如果輸入的停用狀態可能產生改變,也最好在發生時指出,以及其結果為何。例如,在我們的<span class="subtitle"> <a href="http://mdn.github.io/learning-area/accessibility/aria/form-validation-checkbox-disabled.html">form-validation-checkbox-disabled.html</a> </span>展示中,當核取框被核取時,可以讓另一個表單輸入允許輸入更進一步的資訊。我們已經設置一個隱藏的即時區塊:</p>

<pre class="brush: html">&lt;p class="hidden-alert" aria-live="assertive"&gt;&lt;/p&gt;</pre>

<p>這是使用絕對位置從視窗中隱藏。當核取/未核取時,我們更新在隱藏的即時區塊中的文字,告訴螢幕報讀器使用者選取這個核取框時結果會是甚麼,以及更新 <code>aria-disabled</code> 的狀態,連同一些視覺的指示:</p>

<pre class="brush: js">function toggleMusician(bool) {
  var instruItem = formItems[formItems.length-1];
  if(bool) {
    instruItem.input.disabled = false;
    instruItem.label.style.color = '#000';
    instruItem.input.setAttribute('aria-disabled', 'false');
    hiddenAlert.textContent = 'Instruments played field now enabled; use it to tell us what you play.';
  } else {
    instruItem.input.disabled = true;
    instruItem.label.style.color = '#999';
    instruItem.input.setAttribute('aria-disabled', 'true');
    instruItem.input.removeAttribute('aria-label');
    hiddenAlert.textContent = 'Instruments played field now disabled.';
  }
}</pre>

<h4 id="描述非語意按鈕為按鈕">描述非語意按鈕為按鈕</h4>

<p>本課程我們已經談過幾次按鈕、連結或表單元素(參見HTML無障礙文章的 <a href="/en-US/docs/Learn/Accessibility/HTML#UI_controls">UI controls</a> ,以及前述<a href="#增強鍵盤無障礙">增強鍵盤無障礙</a>的原生無障礙(以及在使用其他元素偽造背後的無障礙議題)。基本上,使用 <code>tabindex</code> 與一些 JavaScript,在很多情況下,你可以在沒有太多困難下增加鍵盤無障礙支援功能。</p>

<p>但螢幕報讀器的情況如何呢?他們仍然無法將這些元素視為按鈕。如果我們用螢幕報讀器測試我們的 <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">fake-div-buttons.html</a> 範例,我們偽造的按鈕將會用句子如 "Click me!, group"讀出,很顯然地令人困惑。</p>

<p>我們可以使用WAI-ARIA角色來修正它。請複製 <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">fake-div-buttons.html</a>在本機,並且對每個按鈕<code>&lt;div&gt;</code>增加  <code><a href="https://www.w3.org/TR/wai-aria-1.1/#button">role="button"</a></code> ,範例如下:</p>

<pre>&lt;div data-message="This is from the first button" tabindex="0" role="button"&gt;Click me!&lt;/div&gt;</pre>

<p>現在當你使用螢幕報讀器測試它時,按鈕將會用句子如"Click me!, button" 讀出—這樣好多了。</p>

<div class="note">
<p>注意:記住最好盡可能使用正確的語意元素,如果你希望創建一個按鈕,並且可使用 {{htmlelement("button")}} 元素,就應該使用 {{htmlelement("button")}} 元素!</p>
</div>

<h4 id="透過複雜的插件引導使用者">透過複雜的插件引導使用者</h4>

<p>除了標準HTML可用外,還有一堆其他<a href="https://www.w3.org/TR/wai-aria-1.1/#role_definitions">角色</a>可以辨識非語意的元素結構作為一般的使用者介面特徵,例如 <code><a href="https://www.w3.org/TR/wai-aria-1.1/#combobox">combobox</a></code>, <code><a href="https://www.w3.org/TR/wai-aria-1.1/#slider">slider</a></code>, <code><a href="https://www.w3.org/TR/wai-aria-1.1/#tabpanel">tabpanel</a></code>, <code><a href="https://www.w3.org/TR/wai-aria-1.1/#tree">tree</a></code>。你可在 <a href="https://dequeuniversity.com/library/">Deque university code library</a>中找到很多有用的範例,可給你這些控制措施如何做到無障礙的想法。</p>

<p>我們來看看我們自己的範例,我們回到我們簡單的絕對位置頁籤的介面(參見在我們的CSS與JavaScript無障礙文章中的 <a href="/en-US/docs/Learn/Accessibility/CSS_and_JavaScript#Hiding_things">Hiding things</a> ),你可以找到 <a href="http://mdn.github.io/learning-area/css/css-layout/practical-positioning-examples/info-box.html">頁籤資訊框範例</a>(看<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/practical-positioning-examples/info-box.html">原始碼</a>).</p>

<p>本範例以鍵盤無障礙而言運作正常—你可以開心地在不同的頁籤間跳位,並且選擇他們顯示該頁籤的內容,也相當地容易操作—你可以滾動內容並使用標題來導覽,即使你看不到螢幕上正發生的事情。然而內容是甚麼並非很明顯—螢幕報讀器目前以連結的清單報讀內容,以及有三個標題的內容。這樣無法給你了解內容之間的關係。最好給予使用者更多關於內容結構的線索。</p>

<p>為改善這些,我們創建新的範例版本為 <a href="https://github.com/mdn/learning-area/blob/master/accessibility/aria/aria-tabbed-info-box.html">aria-tabbed-info-box.html</a> (<a href="http://mdn.github.io/learning-area/accessibility/aria/aria-tabbed-info-box.html">看實際頁面</a>),我們已經更新頁籤介面的結構如下:</p>

<pre class="brush: html">&lt;ul role="tablist"&gt;
  &lt;li class="active" role="tab" aria-selected="true" aria-setsize="3" aria-posinset="1" tabindex="0"&gt;Tab 1&lt;/li&gt;
  &lt;li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="2" tabindex="0"&gt;Tab 2&lt;/li&gt;
  &lt;li role="tab" aria-selected="false" aria-setsize="3" aria-posinset="3" tabindex="0"&gt;Tab 3&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="panels"&gt;
  &lt;article class="active-panel" role="tabpanel" aria-hidden="false"&gt;
    ...
  &lt;/article&gt;
  &lt;article role="tabpanel" aria-hidden="true"&gt;
    ...
  &lt;/article&gt;
  &lt;article role="tabpanel" aria-hidden="true"&gt;
    ...
  &lt;/article&gt;
&lt;/div&gt;</pre>

<div class="note">
<p><strong>注意</strong>: 這裡最引人注目的是我們移除在原來範例中的連結,並且只使用清單項目作為頁籤—這樣做是因為對螢幕報讀器使用者比較少困擾(連結並非真正地帶妳到哪個地方;他們只是改變視窗),並且可讓組件大小/位置在組件特徵中有很好的運作—當這些是放在連結上的時候,瀏覽器將維持報讀"1 of 1",而非"1 of 3"、"2 of 3"等。</p>
</div>

<p>新的特徵如下:</p>

<ul>
 <li>新的角色— <code><a href="https://www.w3.org/TR/wai-aria-1.1/#tablist">tablist</a></code>, <code><a href="https://www.w3.org/TR/wai-aria-1.1/#tab">tab</a></code>, <code><a href="https://www.w3.org/TR/wai-aria-1.1/#tabpanel">tabpanel</a></code> — 這些確認頁籤介面的重要區域—頁籤的容器、頁籤本身,以及相對應的頁籤控制盤。</li>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-selected">aria-selected</a></code> — 定義目前被選取的是哪一個頁籤。當不同的頁籤被使用者選取時,本屬性在不同頁籤的值透過JavaScript更新。</li>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-hidden">aria-hidden</a></code> — 隱藏元素不讓螢幕報讀器讀出來。當不同的頁籤被使用者選取時,本屬性在不同頁籤的值透過JavaScript更新。</li>
 <li><code>tabindex="0"</code> — 由於我們已經移除連結,我們需要給予清單項目本屬性,提供鍵盤焦點。</li>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-setsize">aria-setsize</a></code> — T本屬性允許你向螢幕報讀器指定某元素是一系列中的部分,以及該系列有多少項目。</li>
 <li><code><a href="https://www.w3.org/TR/wai-aria-1.1/#aria-posinset">aria-posinset</a></code> — 本屬性允許你指定某個元素在一系列中的位置,伴隨 <code>aria-setsize,</code>提供螢幕報讀器有足夠資訊來告訴你目前的位置在"1 of 3"項目等。在許多情況下,瀏覽器應該可從元素層級結構推測這項資訊,但它肯定有助於提供更多的線索。</li>
</ul>

<p>在我們的測試中,這些新的結構確實提供整體的改善。頁籤現在被認定為頁籤(如螢幕報讀器讀出"索引標籤"),被選取的頁籤以”已選取”指出並讀出頁籤的名稱,螢幕報讀器也告訴你目前所在的頁籤數目。此外,因為設置 <code>aria-hidden</code> (只有非隱藏的頁籤才設定<code>aria-hidden="false"</code> ),非隱藏的頁籤是唯一你可以向下導覽的內容,意即所選取的內容很容易找到。</p>

<div class="note">
<p>注意:如果有任何你很明確地不希望螢幕報讀器讀出的內容,你可賦予它們 <code>aria-hidden="true"</code> 屬性。</p>
</div>

<h2 id="總結">總結</h2>

<p>本文並未涵蓋所有WAI-ARIA的內容,但應該給予你足夠的資訊來了解如何使用它,以及了解一些你會遇到而需要它的最常見型態。</p>

<h2 id="相關參考資訊">相關參考資訊</h2>

<ul>
 <li><a href="https://www.w3.org/TR/wai-aria-1.1/#role_definitions">Definition of Roles</a> — ARIA角色參考資訊。</li>
 <li><a href="https://www.w3.org/TR/wai-aria-1.1/#state_prop_def">Definitions of States and Properties (all aria-* attributes)</a> — 屬性與狀態參考資訊。</li>
 <li><a href="https://dequeuniversity.com/library/">Deque university code library</a> — 實用的範例資源庫,展示使用WAI-ARIA特徵讓複雜的UI控制措施無障礙</li>
 <li><a href="http://w3c.github.io/aria-practices/">WAI-ARIA Authoring Practices</a> — 由W3C發佈之非常詳細的設計模型,解釋如何使用WAI-ARIA特徵實作不同類型的複雜UI控制措施無障礙</li>
 <li><a href="https://www.w3.org/TR/html-aria/">ARIA in HTML</a> — W3C標準針對每一個HTML特徵定義由瀏覽器設置隱含特徵的無障礙(ARIA)語意,以及如果需要額外的語意,你可以設置的WAI-ARIA特徵。</li>
</ul>

<p>{{PreviousMenuNext("Learn/Accessibility/CSS_and_JavaScript","Learn/Accessibility/Multimedia", "Learn/Accessibility")}}</p>

<p> </p>

<h2 id="本模組章節">本模組章節</h2>

<ul>
 <li><a href="/en-US/docs/Learn/Accessibility/What_is_accessibility">何謂無障礙網頁?</a></li>
 <li><a href="/en-US/docs/Learn/Accessibility/HTML">HTML: 無障礙網頁的好開始</a></li>
 <li><a href="/en-US/docs/Learn/Accessibility/CSS_and_JavaScript">充分實踐CSS與JavaScript的無障礙</a></li>
 <li><a href="/en-US/docs/Learn/Accessibility/WAI-ARIA_basics">WAI-ARIA基礎</a></li>
 <li><a href="/en-US/docs/Learn/Accessibility/Multimedia">無障礙多媒體</a></li>
 <li><a href="/en-US/docs/Learn/Accessibility/Mobile">行動無障礙網頁</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility/Accessibility_troubleshooting">無障礙問題排除</a></li>
</ul>

<p> </p>