焦點指標 (通常以「聚焦環表示」) 可識別您網頁上目前聚焦的元素。對於無法使用滑鼠的使用者,這個指標極為重要,因為它可做為滑鼠指標的支架。
如果瀏覽器的預設焦點指標與您的設計衝突,您可以使用 CSS 重新設定樣式。只要謹記鍵盤使用者!
使用 :focus
一律顯示焦點指標
無論聚焦元素的輸入裝置 (滑鼠、鍵盤、觸控筆等) 或用於聚焦該元素的方法為何,系統都會套用 :focus
虛擬類別。例如,下方的 <div>
具有可聚焦的 tabindex
。此外,它的 :focus
狀態也具有自訂樣式:
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
無論使用滑鼠點選按鈕,或使用鍵盤分頁前往分頁,<div>
的外觀一律會相同。
遺憾的是,瀏覽器可能與套用焦點功能的方式不一致。元素是否會接收焦點,取決於瀏覽器和作業系統。
舉例來說,下方的 <button>
也有 :focus
狀態的自訂樣式。
button:focus {
outline: 4px dashed orange;
}
如果在 macOS 的 Chrome 中使用滑鼠按一下 <button>
,應會看到自訂的焦點樣式。不過,如果您在 macOS 的 Safari 中按一下 <button>
,就不會顯示自訂焦點樣式。這是因為在 Safari 中點選元素時,系統不會接收焦點。
由於焦點的行為不一致,可能需要在不同裝置上進行一些測試,確保使用者可接受您的焦點樣式。
使用 :focus-visible
選擇性顯示焦點指標
每當元素收到焦點,且瀏覽器透過經驗法則判定,對使用者有益時,系統就會套用新的 :focus-visible
虛擬類別。具體來說,如果最近一次的使用者互動是透過鍵盤進行,且按下按鍵未包含中繼、ALT
/ OPTION
或 CONTROL
鍵,則 :focus-visible
會相符。
以下範例中的按鈕選擇性會顯示焦點指標。如果使用滑鼠點選按鈕,結果會與首次使用鍵盤按下 Tab 鍵時的結果不同。
button:focus-visible {
outline: 4px dashed orange;
}
使用 :focus-within
設定焦點元素的父項樣式
當元素本身收到焦點時,或該元素中的其他元素收到焦點時,:focus-within
虛擬類別就會套用至元素。
這可用來醒目顯示網頁的某個區域,讓使用者註意到該區域。舉例來說,使用者選取表單,以及選取任一圓形按鈕時,下列表單都會收到焦點。
form:focus-within {
background: #ffecb3;
}
顯示焦點指標的時機
在此建議您問問自己:「如果使用行動裝置時按下這個控制項,您會預期裝置是否顯示鍵盤?」
如果答案為「是」,則無論用於聚焦的輸入裝置為何,控制項都可能「一律」顯示聚焦指標。例如 <input type="text">
元素就是一個很好的例子。無論輸入元素原本如何接收焦點,使用者都必須透過鍵盤將輸入內容傳送至元素,因此建議您一律顯示焦點指標。
如果答案為「否」,控制項可能會選擇性顯示聚焦指標。例如 <button>
元素就是一個很好的例子。如果使用者在滑鼠或觸控螢幕上點選應用程式,代表動作已完成,可能就不需要聚焦指標。不過,如果使用者是使用鍵盤瀏覽,顯示焦點指標會很有幫助,以便使用者決定是否要使用 ENTER
或 SPACE
鍵點選該控制項。
建議不要使用 outline: none
瀏覽器決定繪製焦點指標的時機,實在是很混亂。如果使用 CSS 變更 <button>
元素的外觀,或將元素加上 tabindex
,瀏覽器的預設焦點環行為就會進入啟動畫面。
常見的反模式是使用 CSS 移除焦點指標,例如:
/* Don't do this!!! */
:focus {
outline: none;
}
更好的解決方法是結合 :focus
和 :focus-visible
polyfill。下方第一個程式碼區塊示範 polyfill 的運作方式,下方的範例應用程式提供使用 polyfill 變更按鈕上的焦點指標的範例。
/*
This will hide the focus indicator if the element receives focus via the
mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
/*
Optionally: Define a strong focus indicator for keyboard focus.
If you choose to skip this step, then the browser's default focus
indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
…
}