:focus-visible

Baseline 已廣泛支援

此特性已經十分成熟,可在許多裝置和瀏覽器版本上使用。自 2022 年 3 月起,它已在各瀏覽器中可用。

:focus-visible 偽類在元素匹配 :focus 偽類,並且使用者代理(User Agent)透過啟發式方法確定焦點應該在元素上顯現時應用。(在這種情況下,許多瀏覽器預設會顯示一個“焦點環”。)

試一試

label {
  display: block;
  margin-top: 1em;
}

input:focus-visible {
  outline: 2px solid crimson;
  border-radius: 3px;
}

select:focus-visible {
  border: 2px dashed crimson;
  border-radius: 3px;
  outline: none;
}
<form>
  <p>Which flavor would you like to order?</p>
  <label>Full Name: <input name="firstName" type="text" /></label>
  <label
    >Flavor:
    <select name="flavor">
      <option>Cherry</option>
      <option>Green Tea</option>
      <option>Moose Tracks</option>
      <option>Mint Chip</option>
    </select>
  </label>
</form>

此選擇器可用於根據使用者的輸入模式(滑鼠與鍵盤)提供不同的焦點指示器。

語法

css
:focus-visible {
  /* ... */
}

:focus 與 :focus-visible

最初,使用者代理 CSS 僅根據 :focus 偽類設定焦點樣式,為大多數獲得焦點的元素設定焦點環輪廓。這意味著所有元素,包括所有連結和按鈕,在獲得焦點時都會應用焦點環,許多人認為這很難看。由於外觀問題,一些作者移除了使用者代理的輪廓焦點樣式。更改焦點樣式會降低可用性,而移除焦點樣式則會使有視覺障礙的使用者無法進行鍵盤導航。

瀏覽器不再在每個獲得焦點的元素周圍可見地指示焦點(例如,透過繪製“焦點環”)。相反,它們使用各種啟發式方法僅在對使用者最有幫助時才提供焦點指示器。例如,當使用指向裝置點選按鈕時,通常不會視覺指示焦點,但當需要使用者輸入的文字框獲得焦點時,會指示焦點。雖然當用戶使用鍵盤導航頁面或透過指令碼管理焦點時始終需要焦點樣式,但當用戶知道焦點在哪裡時(例如,當他們使用滑鼠或手指等指向裝置實際將焦點設定在元素上時),則不需要焦點樣式,除非該元素仍需要使用者關注。

:focus 偽類始終匹配當前獲得焦點的元素。:focus-visible 偽類也匹配獲得焦點的元素,但僅當用戶需要被告知焦點當前在哪裡時。由於 :focus-visible 偽類在需要時匹配獲得焦點的元素,因此使用 :focus-visible(而不是 :focus 偽類)允許作者在不改變焦點指示器出現時間的情況下更改焦點指示器的外觀。

當使用 :focus 偽類時,它總是針對當前獲得焦點的元素。這意味著當用戶使用指向裝置時,一個可見的焦點環會出現在獲得焦點的元素周圍,一些人認為這很礙眼。:focus-visible 偽類尊重使用者代理的選擇性焦點指示行為,同時仍然允許焦點指示器自定義。

無障礙

低視力

確保有低視力的人能夠看到視覺焦點指示器。這也將有利於在光線充足的空間(如陽光下)使用螢幕的任何人。WCAG 2.1 SC 1.4.11 非文字對比度要求視覺焦點指示器至少為 3 比 1。

認知

如果一個人使用混合輸入形式,焦點指示器出現和消失的原因可能不明顯。對於有認知問題或技術知識較少的使用者來說,這種互動元素缺乏一致的行為可能會令人困惑。

示例

比較 :focus 和 :focus-visible

此示例展示了三對控制元件。每對都包含一個 text 輸入和一個按鈕。

  • 第一對不為焦點狀態新增任何自定義樣式,並顯示預設情況。
  • 第二對使用 :focus 偽類新增樣式。
  • 第三對使用 :focus-visible 偽類新增樣式。
html
<input type="text" value="Default styles" /><br />
<button>Default styles</button><br />

<input class="focus-only" type="text" value=":focus" /><br />
<button class="focus-only">:focus</button><br />

<input class="focus-visible-only" type="text" value=":focus-visible" /><br />
<button class="focus-visible-only">:focus-visible</button>
css
input,
button {
  margin: 10px;
}

.focus-only:focus {
  outline: 2px solid black;
}

.focus-visible-only:focus-visible {
  outline: 4px dashed darkorange;
}

如果你依次點選每個元素,你會看到當使用 :focus 來設定焦點環樣式時,使用者點選按鈕時使用者代理會繪製焦點環。然而,當使用 :focus-visible 來設定焦點環樣式時,使用者點選按鈕時使用者代理不會繪製焦點環,就像在預設情況下一樣。

如果你接著透過 Tab 鍵遍歷每個元素,你會看到在所有三種情況下——預設、:focus:focus-visible——當用戶使用鍵盤導航到按鈕時,使用者代理都會在按鈕周圍繪製焦點環。

這表明 :focus-visible 如何使設計者能夠遵循瀏覽器邏輯來確定何時應該顯示焦點環。

提供 :focus 回退

如果你的程式碼必須在不支援 :focus-visible 的舊瀏覽器版本中工作,請使用 @supports 檢查 :focus-visible 的支援情況,並在其中重複相同的焦點樣式,但放在 :focus 規則內。請注意,即使你根本沒有為 :focus 指定任何內容,舊瀏覽器也會簡單地顯示原生輪廓,這可能就足夠了。

html
<button class="button with-fallback" type="button">Button with fallback</button>
<button class="button without-fallback" type="button">
  Button without fallback
</button>
css
.button {
  margin: 10px;
  border: 2px solid darkgray;
  border-radius: 4px;
}

.button:focus-visible {
  /* Draw the focus when :focus-visible is supported */
  outline: 3px solid deepskyblue;
  outline-offset: 3px;
}

@supports not selector(:focus-visible) {
  .button.with-fallback:focus {
    /* Fallback for browsers without :focus-visible support */
    outline: 3px solid deepskyblue;
    outline-offset: 3px;
  }
}

規範

規範
選擇器 Level 4
# the-focus-visible-pseudo

瀏覽器相容性

另見