Chrome 開發人員工具中的完整無障礙功能樹狀結構

Johan Bay
Johan Bay

Chrome 開發人員工具推出完整的無障礙樹狀結構,方便開發人員掌握整個樹狀結構的概況。本文將說明如何建立這棵樹,以及如何在工作中使用這棵樹。

什麼是無障礙功能樹狀結構?

螢幕閱讀器等輔助技術會使用 Chromium 的無障礙 API 與網頁內容互動。這個 API 的基礎模型是無障礙樹狀結構:無障礙物件樹狀結構,輔助技術可查詢屬性和資源,並執行相關動作。網頁開發人員主要透過 DOM 屬性 (例如 HTML 的 ARIA 屬性) 塑造及操控無障礙樹狀結構。

Chrome 開發人員工具中,我們提供無障礙功能窗格,協助開發人員瞭解內容如何向輔助技術公開。具體來說,在 DOM 樹狀檢視器中選取節點時,對應的無障礙節點屬性會顯示在窗格中,同時顯示節點的祖系和直接子項的檢視畫面。

Chrome 開發人員工具無障礙功能窗格。

樹狀圖的建立方式為何?

在我們進一步瞭解開發人員工具中全新的完整樹狀檢視畫面之前,讓我們先簡單介紹無障礙樹狀結構的具體概念。無障礙功能樹狀結構是 DOM 樹狀結構的衍生項目。其結構大致相同,但簡化為移除沒有語意內容的節點,例如純粹用於樣式的 <div> 元素。樹狀結構中的每個節點都有一個角色,例如 ButtonHeading,通常會使用 ARIA 屬性或節點內容衍生的名稱。我們來看看 HTML 文件:

<html>
<head>
  <title>How old are you?</title>
</head>
<body>
  <label for="age">Age</label>
  <input id="age" type="number" name="age" value="42">
  <div>
    <button>Back</button>
    <button>Next</button>
  </div>
</body>
</html>

Chromium 中的轉譯器 (名為 Blink) 會擷取內部無障礙樹狀結構,大致如下所示。

role='rootWebArea' focusable name='How old are you?'
  role='genericContainer' ignored
    role='genericContainer' ignored
      role='labelText'
        role='staticText' name='Age'
      role='spinButton' editable focusable name='Age' value='42'
        role='genericContainer' editable
          role='staticText' editable name='42'
      role='genericContainer'
        role='button' focusable name='Back'
          role='staticText' name='Back'
        role='button' focusable name='Next'
          role='staticText' name='Next'

請注意,這個表示法包含多個具有 genericContainer 角色的多餘節點,這似乎與上述聲明相矛盾,即無障礙樹狀結構是 DOM 樹狀結構的簡化衍生樹狀結構。不過,這些節點大多只會出現在內部樹狀結構中,不會向輔助技術公開。由於開發人員工具會直接從轉譯器程序收集無障礙資訊,因此這是開發人員工具處理的樹狀結構表示法。

開發人員工具中的完整無障礙功能樹狀結構

新的完整無障礙功能樹狀結構會與 DOM 樹狀結構同步,方便開發人員在兩個樹狀結構之間切換。我們希望新版樹狀圖更容易探索、更實用且更簡單易用。

您現在已瞭解無障礙樹狀結構的運作方式,可以使用開發人員工具查看新版樹狀結構檢視畫面的外觀。以下 HTML 文件含有標題、標題和兩個按鈕,可用於顯示樹狀結構。

<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
  <button>Back</button>
  <button>Next</button>
</div>

先前的樹狀檢視畫面只能讓您探索單一節點及其祖系。

開發人員工具中的舊版樹狀檢視畫面。

切換至新樹狀結構後,系統會取代 DOM 樹狀結構檢視畫面,讓您查看網頁的完整無障礙功能樹狀結構:

開發人員工具中的全新樹狀檢視畫面。

延遲樹狀結構建構

為了讓樹狀結構在大型網站上也能有良好效能,系統會在探索時,在前端延遲建構樹狀結構。在樹狀結構中展開節點後,系統會透過 Chrome 開發人員工具通訊協定 (CDP) 擷取節點的子項,並重新建構樹狀結構。

新的無障礙功能樹狀結構,顯示大型網頁的結果。

直播

如果轉譯器中的無障礙樹狀結構有所變更,新的樹狀檢視畫面會即時更新。它會連結至相同的機制,以便通知輔助技術樹狀結構的變更,並使用該機制將事件傳送至開發人員工具前端,以便更新節點。實際上,CDP 後端會監聽樹狀結構的更新,追蹤先前要求的節點,並在任何節點發生變更時,將事件傳送至 DevTools 前端。

許多樹木的故事

在「無障礙樹狀結構的定義」一節中,您已瞭解 Blink 如何為要轉譯的 DOM 建構無障礙樹狀結構,而 DevTools 則會透過 CDP 擷取這個樹狀結構。雖然這是事實,但我們在說明中省略了一些複雜的部分。實際上,在 Chromium 中有許多不同方式可以體驗無障礙樹狀結構。在為開發人員工具設計新的樹狀檢視畫面時,我們在過程中做出了一些選擇,決定要顯示 Chromium 哪些無障礙功能內部資訊。

平台

每個平台都有不同的無障礙 API,雖然樹狀結構的形狀在所有平台上都相同,但用於與樹狀結構互動的 API 不同,屬性名稱也可能不同。開發人員工具會顯示 Chromium 的內部樹狀結構,其中的角色和屬性通常會與 ARIA 規格中定義的角色和屬性相符。

多個影格和網站隔離

由於 Chromium 不僅會將每個分頁的內容放入不同的轉譯器程序,還會將跨網站文件隔離在不同的轉譯器程序中,因此我們必須透過 CDP 個別連線至每個子程序外子文件,並擷取其無障礙樹狀結構。接著,我們會在前端將這些子樹縫合在一起,營造出一個連貫樹狀結構的錯覺,即使這些樹狀結構位於 Chromium 中的不同轉譯器程序中。

已忽略且不感興趣的節點

我們會預設隱藏部分節點:已略過的節點,以及角色為「一般」且沒有名稱的節點。這些節點不具語意意義,如果是忽略的節點,則不會提供給輔助技術。我們會隱藏這些節點,避免樹狀檢視畫面過於雜亂。如果沒有這麼做,大多數網頁的無障礙樹狀結構會變成這樣:

顯示所有節點的新樹狀檢視畫面。

這裡的警告是,這基本上表示我們需要建構另一個樹狀結構,而非後端提供的樹狀結構。舉例來說,假設我們有 A、B、C 和 X 節點,其中 A 有子節點 X 和 B,而 X 有子節點 C。如果 X 是已略過的節點,我們會從樹狀結構中移除 X,改為建立一個樹狀結構,其中 C 是 A 的子項。

圖表顯示樹狀結構的修剪方式。

在前端,我們會建構包含忽略節點的完整樹狀結構,並在顯示節點之前移除這些節點。我們這麼做的原因有兩個:

  • 這麼做可讓後端更輕鬆地處理節點更新,因為兩個端點都採用相同的樹狀結構。舉例來說,如果在本例中移除節點 B,我們會收到節點 X 的更新 (因為子項已變更),但如果我們移除該節點,就很難判斷要更新哪些項目。
  • 這可確保所有 DOM 節點都有對應的無障礙節點。切換樹狀結構時,我們會選取與 DOM 樹狀結構中目前選取的節點相對應的節點。因此,就前述範例而言,如果使用者在切換樹狀結構時選取了對應於 X 的 DOM 節點,我們會在節點 A 和 B 之間插入 X,並在樹狀結構中選取 X。這可讓使用者檢查所有 DOM 節點的無障礙性節點,並協助判斷系統為何忽略該節點。

未來構想

推出新的無障礙樹狀結構只是起步,我們有幾個想法,希望日後的專案可以以新版檢視畫面為基礎,但也非常期待聽取你的意見回饋

其他篩選方式

如上所述,我們目前會篩除不感興趣的節點。我們可以提供一種方法來停用這項行為並顯示所有節點,或是提供其他篩選方式,例如「顯示地標節點」或「顯示標題」

標明 a11y 問題

我們可以將「無障礙功能最佳做法」分析納入樹狀結構,並直接在有問題的節點上醒目顯示無障礙功能問題。

在開發人員工具中顯示無障礙功能操作

我們目前顯示的樹狀圖是單向的,可讓我們瞭解瀏覽特定網頁時,哪些資訊會提供給輔助技術。無障礙工具動作代表另一方向的通訊:讓輔助技術可對呈現的 UI 採取行動。我們可以在開發人員工具中顯示這類動作,讓輔助技術可透過 API 執行「點擊」、「捲動」或變更頁面值等動作。