CSS 屬性 appearance: base-select 可讓您像一般 HTML 元素一樣,設定 <select> 元素及其挑選器 (透過 ::picker(select)) 的樣式。結合 Grid 或 Flexbox 等現代 CSS 版面配置技術,您就能擺脫傳統的堆疊垂直清單,並建立豐富的視覺體驗,而不必使用自訂 JS。舉例來說,您可以使用 display: grid 將選項設為 2D 格狀資訊卡。
這項功能適合用於顏色挑選器、表情符號選取器或產品子類,因為豐富的視覺選單比清單更有效。
導入方式
1. 啟用基本樣式
將 appearance: base-select 套用至 <select> 元素及其內部挑選器虛擬元素 select::picker(select):
select.grid-picker {
&, &::picker(select) {
appearance: base-select;
}
}
2. 設定挑選器容器的樣式
指定 select:open::picker(select) 並套用 display: grid (或 display: flex)。
定義欄和間距,方法與任何容器相同。
select.grid-picker:open::picker(select) {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
}
重要事項::open 為必要欄位。如果設定 select::picker(select) 的樣式,即使選取器關閉,選取器仍會顯示!
3. 設定選項樣式
指定 <option> 元素,將其樣式設為格線項目或資訊卡。您可以在其中加入圖片、SVG 或複雜的版面配置。
/* Style options as grid cards */
.grid-picker option {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* padding, border-radius, background, etc. */
}
4. 設定所選選項的樣式
如要設定所選選項的樣式,請使用 option:checked。例如:
.grid-picker option:checked {
position: relative;
border: 2px solid var(--primary-color);
background-color: oklab(from var(--primary-color) l a b / 8%);
}
與任何 UI 控制項一樣,請勿僅以顏色傳達狀態,並使用多個視覺指標 (例如顏色、邊框粗細、勾號) 傳達所選選項。
5. (選用) 設定所選選項勾號的樣式
根據預設,瀏覽器會將勾號算做每個 <option> 的第一個子項。
其行為類似於含有 ::before 的 content: "✓" / "",會在作者提供的 ::before (如有) 之前算繪。
如果未選取該選項,系統會透過 visibility: hidden 隱藏勾號。
您可以使用 ::checkmark 虛擬元素設定樣式,或在只想透過樣式傳達選取狀態或使用自訂指標時,完全隱藏該元素。
舉例來說,如要將徽章放在選項的右上角,可以執行以下操作:
select.grid-picker {
> option::checkmark {
/* Hide the checkmark for unselected options */
display: none;
}
> option:checked {
position: relative;
&::checkmark {
position: absolute;
inset-block-start: -.4em;
inset-inline-end: -.5em;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-inline-size: 1.6em;
aspect-ratio: 1;
padding-right: 0.12em;
padding-left: 0.05em;
border-radius: 50%;
background: var(--primary-color);
color: white;
font-size: 70%;
font-weight: bold;
}
}
}
提示:在勾號周圍繪製容器 (例如圓形) 時,請將容器稍微向上移動 (如我們在此處使用 padding-bottom 和 padding-left 的做法),以便根據其形狀進行視覺置中。請勿使用 padding-inline-start 或 padding-block-end,因為這些屬性會根據書寫模式而變更,但勾號的形狀不會。
6. (選用) 自訂所選選項的顯示方式
根據預設,<select> 會顯示所選選項的純文字版本。如要為所選值顯示多媒體內容,請在 <button> 中使用 <selectedcontent>,和/或以不同方式顯示所選選項 (例如隱藏特定詳細資料)。
請勿使用未加上 <button> 的 <selectedcontent>,因為 <selectedcontent> 會像其他內容元素一樣,直接成為挑選器的一部分。
最佳做法
- 測試版面配置行為。設定
appearance: base-select會移除預設的瀏覽器行為,也就是根據最長的選項寬度調整選取範圍大小。您可能需要設定固定寬度,或使用彈性/格線限制,避免版面配置位移。 - 確認
<select>具有name屬性和相關聯的<label>。這樣一來,即使使用自訂 UI,螢幕閱讀器仍可存取元件,且元件能與標準表單提交作業搭配運作。 - 在選項中使用標準
value屬性,確保表單提交功能與先前完全相同。
無障礙設定
原生 <select> 只會處理線性向上/向下箭頭導覽,因此在開啟的挑選器中,向左/向右不會執行任何動作,而向上/向下仍會依序瀏覽項目,無論資料列和資料欄為何。
如要實作遵循格線的空間導覽,您可以攔截 keydown,並在使用方向鍵時,將焦點導向按下方向上最接近的選項 (例如使用 getBoundingClientRect())。如要判斷適當的下一個/上一個項目,請使用在實際幾何圖形上運作的 DOM 方法 (例如 getBoundingClientRect()),而非剖析 grid-template-columns 或 grid-column 等 CSS 字串,因為這類字串在複雜的網格、子網格、RTL 和其他版面配置情境中可能不穩定且容易出錯。不過,請勿過度設計;請使用您知道的版面配置不變量,簡化這項邏輯。
注意:這僅適用於鍵盤操作。<select> 和其 ::picker() 仍具有預設角色 (menu 或 listbox),且無法覆寫,也不允許包含具有 role="grid" 的元素。在挑選器中巢狀結構化 role="grid" 包裝函式,在實務上可行,但並非有效做法,且可能會讓輔助技術使用者感到困惑。
在某些情況下,使用 <optgroup> 將選項分組,即使不使用 role="grid",也能提供良好的螢幕閱讀器使用者體驗。否則,最終可能需要改用自訂解決方案,使用彈出式視窗 API、錨定定位和 role="grid",為螢幕閱讀器使用者提供所需的使用者體驗。
備用策略
可自訂 <select> 的備用方案和瀏覽器支援
如果瀏覽器尚未支援 appearance: base-select,<select> 元素會正常降級為標準作業系統下拉式選單。
- 忽略非文字內容:舊版瀏覽器會移除
<option>標記內的 HTML 代碼 (例如<svg>或<div>),只轉譯文字節點。確保<option>的文字內容本身清晰可讀且有意義。 - HTML 結構處理:標準剖析器可能會忽略
<select>內的<button>和<selectedcontent>標記,或將其視為無效。如果將標準文字視為可讀取的備用文字,則不需要使用繁重的 JavaScript 填充碼來進行漸進式增強。
document.addEventListener("DOMContentLoaded", () => {
// Check if browser supports base-select value
if (!CSS.supports("appearance", "base-select")) {
// Custom select overrides are not supported natively.
}
});