當 CSS 不夠用時:可訪問組件的 JavaScript 要求
已發表: 2022-03-10作為 ModernCSS.dev 的作者,我是 CSS 解決方案的大力支持者。 而且,我喜歡看到人們使用 CSS 進行真正開箱即用的設計和交互性的巧妙方式! 然而,我注意到使用“checkbox hack”之類的方法來推廣“純 CSS”組件的趨勢。 不幸的是,像這樣的黑客攻擊使大量用戶無法使用您的界面。
本文介紹了幾個常見的組件,以及為什麼 CSS 不足以通過詳細說明 JavaScript 要求來涵蓋可訪問性。 這些要求基於 Web 內容可訪問性指南 (WCAG) 和可訪問性專家的額外研究。 我不會規定 JavaScript 解決方案或演示 CSS,而是檢查創建每個組件時需要考慮的內容。 JavaScript 框架當然可以使用,但不是為了添加所討論的事件和特性所必需的。
列出的要求基本上不是可選的——它們是幫助確保組件的可訪問性所必需的。
如果您使用的是框架或組件庫,您可以使用本文來幫助評估所提供的組件是否滿足可訪問性要求。 重要的是要知道,上面提到的許多項目不會被 aXe 等自動化可訪問性測試工具完全覆蓋,因此需要一些手動測試。 或者,您可以使用賽普拉斯之類的測試框架來為所需功能創建測試。
請記住,本文的重點是讓您了解每個界面組件的 JavaScript 注意事項。 對於創建完全可訪問的組件(例如必要的 aria 甚至標記)的所有實現細節,這並不是一個全面的資源。 每種類型都包含資源,以幫助您更多地了解每個組件的更廣泛考慮因素。
確定僅 CSS 是否是合適的解決方案
在繼續使用純 CSS 解決方案之前,有幾個問題要問。 我們將在更多上下文中介紹此處介紹的一些術語及其相關組件。
- 這是為了你自己的享受嗎?
然後絕對全力以赴地使用 CSS,突破界限,學習這門語言可以做什麼! - 該功能是否包括顯示和隱藏內容?
然後,您需要 JS 至少切換 aria 並啟用Esc
關閉。 對於也會改變狀態的某些類型的組件,您可能還需要通過觸發 ARIA 活動區域內的更新來傳達更改。 - 自然對焦順序是不是最理想?
如果自然順序失去了觸發器與其觸發的元素之間的關係,或者鍵盤用戶甚至無法通過自然 Tab 順序訪問內容,那麼就需要 JS 來輔助焦點管理。 - 程式化控件是否提供有關功能的正確信息?
屏幕閱讀器等輔助技術的用戶接收基於語義和 ARIA 的信息,幫助他們確定控件的作用。 而且,語音識別的用戶需要能夠識別組件的標籤或類型,以計算出用於操作控件的短語。 例如,如果您的組件的樣式類似於選項卡,但使用單選按鈕像選項卡一樣“工作”,則屏幕閱讀器可能會聽到“單選按鈕”,而語音用戶可能會嘗試使用“選項卡”一詞來操作它們。 在這些情況下,您將需要 JS 來啟用使用適當的控件和語義來實現所需的功能。 - 效果是否依賴懸停和/或焦點?
然後,您可能需要 JS 協助提供替代解決方案,以提供對內容的平等訪問或持久訪問,特別是對於觸摸屏用戶和使用 200%+ 桌面縮放或放大軟件的用戶。
快速提示:創建任何類型的自定義控件時的另一個參考是 W3“使用 ARIA”指南中的自定義控件可訪問開發清單。 這提到了上面的幾點,還有一些額外的設計和語義考慮。
工具提示
縮小工具提示的定義有點棘手,但在本節中,我們將討論鼠標懸停在觸發元素附近時出現的小文本標籤。 它們覆蓋其他內容,不需要交互,並在用戶移除懸停或焦點時消失。
這裡的純 CSS 解決方案可能看起來完全沒問題,可以通過以下方式完成:
<button class="tooltip-trigger">I have a tooltip</button> <span class="tooltip">Tooltip</span> .tooltip { display: none; } .tooltip-trigger:hover + .tooltip, .tooltip-trigger:focus + .tooltip { display: block; }
然而,這忽略了相當多的可訪問性問題,並排除了許多用戶訪問工具提示內容。
一大群被排除在外的用戶是那些使用觸摸屏的用戶,其中:hover
可能不會被觸發,因為在觸摸屏上, :hover
事件與:focus
事件同步觸發。 這意味著連接到觸發元素的任何相關操作(例如按鈕或鏈接)都將與顯示的工具提示一起觸發。 這意味著用戶可能會錯過工具提示,或者沒有時間閱讀其內容。
在工具提示附加到沒有事件的交互式元素的情況下,工具提示可能會顯示但不會被關閉,直到另一個元素獲得焦點,同時可能會阻止內容並阻止用戶執行任務。
此外,需要使用縮放或放大軟件進行導航的用戶在使用工具提示時也會遇到相當大的障礙。 由於工具提示在懸停時顯示,如果這些用戶需要通過平移屏幕來更改他們的視野以閱讀工具提示,它可能會導致它消失。 工具提示也會從用戶那裡移除控制權,因為通常沒有什麼可以告訴用戶工具提示會提前出現。 內容的覆蓋可能會阻止他們執行任務。 在某些情況下,例如綁定到表單域的工具提示、移動設備或其他屏幕鍵盤可能會掩蓋工具提示內容。 而且,如果它們沒有適當地連接到觸發元素,一些輔助技術用戶甚至可能不知道出現了工具提示。
工具提示行為的指導來自 WCAG Success Criterion 1.4.13 - Content on Hover or Focus。 該標準旨在幫助低視力用戶和使用變焦和放大軟件的用戶。 工具提示(以及出現在懸停和焦點上的其他內容)的指導原則包括:
- 可解僱
無需移動懸停或焦點即可關閉工具提示 - 可懸停
顯示的工具提示內容可以懸停而不會消失 - 執著的
附加內容不會因為超時而消失,而是等待用戶移除懸停或焦點或以其他方式關閉它
要完全符合這些準則,需要一些 JavaScript 幫助,尤其是允許關閉內容。
- 輔助技術的用戶會假設解僱行為與Esc鍵相關,這需要 JavaScript 偵聽器。
- 根據下一節中描述的 Sarah Higley 的研究,在工具提示中添加可見的“關閉”按鈕也需要 JavaScript 來處理其關閉事件。
- JavaScript 可能需要增強您的樣式解決方案,以確保用戶可以將鼠標懸停在工具提示內容上,而不會在用戶移動鼠標時將其關閉。
工具提示的替代品
工具提示應該是最後的手段。 Sarah Higley - 一位對勸阻使用工具提示特別熱衷的可訪問性專家 - 提供了這個簡單的測試:
“我為什麼要將此文本添加到 UI 中? 還能去哪裡?”
— Sarah Higley 來自演講“工具提示:分為四個部分的調查”
根據 Sarah 在 Microsoft 擔任職務時所參與的研究,另一種解決方案是專門的“toggletip”。 本質上,這意味著提供一個額外的元素來允許用戶有意觸發額外內容的顯示和隱藏。 與工具提示不同,切換提示可以保留顯示內容中元素的語義。 它們還讓用戶重新控制切換它們,並保留更多用戶,特別是觸摸屏用戶的可發現性和可操作性。
如果您記得title
屬性存在,只需知道它會遇到我們在純 CSS 解決方案中提到的所有相同問題。 換句話說 - 不要在假設它是可接受的工具提示解決方案的情況下使用title
。
有關更多信息,請查看 Sarah 在 YouTube 上的演示文稿以及她關於工具提示的大量文章。 要了解有關 tooltips 與 toggletips 的更多信息以及有關為什麼不使用title
的更多信息,請查看 Heydon Pickering 的 Inclusive Components: Tooltips and Toggletips 文章。
模態
模態框(也稱為燈箱或對話框)是在觸發操作後出現的頁內窗口。 它們覆蓋其他頁面內容,可能包含結構化信息,包括附加操作,並且通常具有半透明背景以幫助將模式窗口與頁面的其餘部分區分開來。
我已經看到了一些純 CSS 模式的變體(並且為我的投資組合的舊版本製作了一個感到內疚)。 他們可能會使用“checkbox hack”,利用:target
的行為,或者嘗試使用:focus
來改造它(這可能真的是一個變相的過大工具提示)。
至於 HTML dialog
元素,請注意它不被認為是全面可訪問的。 因此,雖然我絕對鼓勵人們在自定義解決方案之前使用原生 HTML,但不幸的是,這打破了這個想法。 您可以了解有關 HTML dialog
為何不可訪問的更多信息。
與工具提示不同,模式旨在允許結構化內容。 這意味著潛在的標題、一些段落內容和交互式元素,如鍊接、按鈕甚至表單。 為了讓大多數用戶訪問該內容,他們必須能夠使用鍵盤事件,尤其是選項卡。 對於較長的模態內容,箭頭鍵還應保留滾動功能。 和工具提示一樣,它們應該可以用Esc鍵關閉——而且沒有辦法只用 CSS 來啟用它。
模態框內的焦點管理需要 JavaScript。 模態框應該捕獲焦點,這意味著一旦焦點在模態框內,用戶不應該能夠將其跳出到它後面的頁面內容中。 但首先,焦點必須進入模態,這也需要 JavaScript 才能獲得完全可訪問的模態解決方案。
以下是必須使用 JavaScript 管理的與模式相關的事件序列:
- 按鈕上的事件偵聽器打開模式
- 焦點放在模態中; 哪個元素根據模態內容而變化(參見決策樹)
- 焦點被困在模態中,直到它被解除
- 優選地,如果需要確認模式內容,除了專用關閉按鈕或諸如“取消”之類的破壞性按鈕動作之外,用戶還能夠使用Esc鍵關閉模式
- 如果允許Esc ,則單擊模態背景也應關閉模態
- 解除後,如果未發生導航,則焦點將重新放在觸發按鈕元素上
模態焦點決策樹
基於 WAI-ARIA 創作實踐模態對話框示例,這裡是一個簡化的決策樹,用於在打開模態後將焦點放在何處。 上下文將始終決定這裡的選擇,理想情況下,焦點比簡單的“第一個可聚焦元素”更進一步管理。 事實上,有時需要選擇不可聚焦的元素。
- 模態的主要主題是一種形式。
關注第一個表單域。 - 模態內容的長度很重要,並且會將模態動作推到視野之外。
關注標題(如果存在)或第一段。 - 模態的目的是具有多個可用操作的程序性(例如:操作確認)。
專注於基於上下文的“破壞性最小”操作(例如:“OK”)。 - 模態的目的是一個動作的程序。
專注於第一個可聚焦元素
快速提示:在需要聚焦不可聚焦元素(例如標題或段落)的情況下,添加tabindex="-1"
允許元素以編程方式通過 JS 聚焦但不將其添加到 DOM 選項卡順序.
有關設置 ARIA 的其他要求以及有關如何選擇要添加焦點的元素的其他詳細信息,請參閱 WAI-ARIA 模態演示。 該演示還包括 JavaScript 以舉例說明如何進行焦點管理。
對於現成的解決方案,Kitty Giraudel 創建了一個包含我們討論的功能要求的 11y 對話框。 Adrian Roselli 還研究了模態對話框的焦點管理,並創建了一個演示並彙編了有關不同瀏覽器和屏幕閱讀器組合如何傳達焦點元素的信息。
標籤
選項卡式界面涉及一系列觸發器,一次顯示一個相應的內容面板。 您可能會發現這些 CSS “hacks”涉及使用風格化的單選按鈕或:target
,它們都允許一次只顯示一個面板。
以下是需要 JavaScript 的選項卡功能:
- 將
aria-selected
屬性切換為當前選項卡的 true 和未選擇的選項卡的 false - 創建一個巡迴標籤索引以區分標籤選擇和焦點
- 通過響應箭頭鍵事件(以及可選的
Home
和End
)在選項卡之間移動焦點
或者,您可以使選項卡選擇跟隨焦點 - 這意味著當選項卡獲得焦點時,它也會被選中並顯示其關聯的選項卡面板。 WAI-ARIA 創作實踐提供了本指南,用於選擇是否應關注焦點。
無論您是否選擇讓選擇跟隨焦點,您還將使用 JavaScript 偵聽箭頭鍵事件以在選項卡元素之間移動焦點。 這是一種允許選項卡選項導航的替代模式,因為使用漫遊選項卡索引(如下所述)會改變自然的鍵盤選項卡焦點順序。
關於 Roving tabindex
漫遊tabindex的概念是tabindex
值的值是通過程序控制來管理元素的焦點順序的。 關於選項卡,這意味著通過設置tabindex="0"
,只有選定的選項卡是焦點順序的一部分,而未選定的選項卡被設置為tabindex="-1"
,這會將它們從自然鍵盤焦點順序中刪除。
這樣做的原因是,當選擇一個選項卡時,下一個選項卡會將用戶的焦點放在相關的選項卡面板中。 您可以選擇通過為其分配tabindex="0"
來使作為選項卡面板的元素具有焦點,或者如果保證選項卡面板中的可焦點元素,則可能沒有必要。 如果您的選項卡面板內容將更加多變或複雜,您可以考慮根據我們為模態審查的決策樹來管理焦點。
示例選項卡模式
以下是創建選項卡的一些參考模式:
- 來自 Deque 大學的 Tabpanel 演示
- Scott O'Hara 的標籤小部件測試(測試幾種功能模式)
- Heydon Pickering 的Inclusive Components中的選項卡式界面,它演示了選項卡如何逐步增強目錄
旋轉木馬
輪播也稱為幻燈片或滑塊,涉及一系列旋轉內容面板(也稱為“幻燈片”),其中包括控制機制。 您會在許多配置中找到這些內容,並且內容範圍很廣。 眾所周知,它們被認為是一種糟糕的設計模式。
關於純 CSS 輪播的棘手部分是它們可能不提供控件,或者它們可能使用意想不到的控件來操縱輪播運動。 例如,您可以再次使用“checkbox hack”來使輪播轉換,但複選框會向輔助技術用戶傳遞錯誤類型的交互信息。 此外,如果您將復選框標籤設置為在視覺上顯示為向前和向後箭頭,您可能會給語音識別軟件的用戶一個錯誤的印象,即他們應該說些什麼來控制輪播。
最近,對滾動捕捉的原生 CSS 支持已經落地。 起初,這似乎是完美的純 CSS 解決方案。 但是,即使是自動可訪問性檢查也會將這些標記為鍵盤用戶無法導航的,以防無法通過交互式元素導航它們。 此功能的默認行為還有其他可訪問性和用戶體驗問題,其中一些我已包含在 SmolCSS 上的滾動快照演示中。
儘管輪播的外觀多種多樣,但仍有一些共同特徵。 一種選擇是使用標籤標記創建輪播,因為它實際上是相同的底層界面,但視覺呈現有所改變。 與標籤相比,輪播可能會為上一個和下一個提供額外的控制,如果輪播自動播放,也會暫停。
以下是 JavaScript 的注意事項,具體取決於您的輪播功能:
- 使用分頁控件
選擇編號項目後,以編程方式聚焦關聯的輪播幻燈片。 這將涉及使用漫遊 tabindex 設置幻燈片容器,以便您可以聚焦當前幻燈片,但防止訪問屏幕外幻燈片。 - 使用自動播放
包括一個暫停控件,並且還可以在幻燈片懸停或其中的交互式元素獲得焦點時啟用暫停。 此外,您可以檢查 JavaScript 中的prefers-reduced-motion
以在暫停狀態下加載幻燈片以尊重用戶偏好。 - 使用上一個/下一個控件
包括一個標記為aria-live="polite"
的視覺隱藏元素,並在激活這些控件後,使用當前位置的指示填充實時區域,例如“Slide 2 of 4”。
構建無障礙旋轉木馬的資源
- 完整的實現細節和注意事項以及來自 W3C Web Accessibility 輪播教程的完整代碼示例
- Deque大學將tab界面增強為輪播的例子
- 自動旋轉圖像輪播的 WAI-ARIA 創作實踐示例
- Smashing 的可訪問組件綜述中的輪播資源選擇
下拉菜單
這是指一個組件,其中按鈕切換打開鏈接列表,通常用於導航菜單。 停止在:hover
或:focus
上顯示菜單的 CSS 實現只會錯過一些重要的細節。
我承認,我什至認為通過使用更新的:focus-within
屬性,我們可以安全地實現純 CSS 解決方案。 您會看到我關於 CSS 下拉菜單的文章已被修改,以包含有關必要 JavaScript 的註釋和資源(我保留了標題,以便尋求該解決方案的其他人也有望完成 JS 實現)。 具體來說,僅依賴 CSS 意味著違反了 WCAG 成功標準 1.4.13:我們通過工具提示了解到的懸停或焦點內容。
我們需要在 JavaScript 中添加一些此時聽起來應該很熟悉的技術:
- 通過監聽
click
事件在true
之間切換菜單按鈕上的aria-expanded
false
- 使用Esc鍵關閉打開的菜單,並將焦點返回到菜單切換按鈕
- 最好在焦點移到菜單外時關閉打開的菜單
- 可選:實現箭頭鍵以及
Home
和End
鍵,用於在菜單切換按鈕和下拉菜單中的鏈接之間進行鍵盤導航
快速提示:通過將菜單顯示與.dropdown-toggle[aria-expanded=
"
true
"
] + .dropdown
的選擇器相關聯,而不是將菜單顯示基於附加 JS- 的存在,確保下拉菜單的正確實現添加了類似active
的類。 這也消除了 JS 解決方案的一些複雜性!
這也稱為“披露模式”,您可以在 WAI-ARIA 創作實踐的示例披露導航菜單中找到更多詳細信息。
有關創建可訪問組件的其他資源
- Smashing 的可訪問前端組件完整指南
- Carie Fisher 的文章 Good, Better, Best:解開可訪問模式的複雜世界
- WAI-ARIA 創作實踐 1.2 中提供的常見設計模式和小部件的演示和信息
- Deque 大學的代碼庫
- Scott O'Hara 的無障礙組件
- Heydon Pickering 的包容性組件