產生 CSS 切換開關時的常見錯誤可分為四類:移除原生核取方塊行為、選擇會讓旋鈕超出軌道的軌道尺寸、挑選對比不足或僅依賴色相的顏色,以及將控制項以會停用 Space 鍵啟動或表單送出方式接入框架。CSS 切換開關產生器以原生 HTML 核取方塊為核心,因此最傷的就是那些丟掉原生行為的錯誤——使用 display: none 隱藏輸入框、將其改為 button 或 div,或移除賦予控制項可存取名稱的可見標籤。幾何尺寸的錯誤看起來不同,但同樣顯眼:軌道高度相對太窄、padding 沒留空間給旋鈕,或 translateX 距離與所選寬度不符,都會導致旋鈕被裁切、平貼或飄出軌道。色彩錯誤會傷害辨識度,因為低對比的開啟狀態或與軌道同色的旋鈕會融入頁面。下方各章節會逐一說明每一類錯誤、解釋 CSS 切換開關產生器 如何避免最嚴重的版本,並展示如何在你的頁面中驗證最終結果。

會剝奪原生核取方塊行為的錯誤
原生核取方塊是切換開關具備可存取性的關鍵:它提供勾選狀態、Space 鍵啟動、聚焦,以及表單送出。手寫 CSS 切換開關程式碼時,最常見的錯誤就是把這些特性丟掉。
在輸入框上使用 display: none 會將其完全移出 tab 順序。鍵盤使用者再也無法到達該控制項,螢幕閱讀器也無法朗讀它。CSS 切換開關產生器以 appearance: none 隱藏預設繪製,而原生輸入框仍持續支援勾選狀態、Space 鍵啟動、聚焦與表單送出。W3C CSS Basic User Interface Level 4 規格定義了相同行為:appearance 僅控制視覺繪製,不影響底層語意。
將輸入框替換為 button 或 div 會捨棄二元的表單狀態。button 會切換按壓狀態,但不會在表單中送出 name=value 配對。div 完全沒有語意,必須再加上 ARIA 角色與自訂鍵盤處理,才能等同於核取方塊本身提供的功能。產生器保留 input type checkbox,讓既有的表單流程持續運作,包括許多產品接到 change 處理器的表單送出步驟。
第三個常見錯誤是移除可見標籤。沒有標籤,輸入框就沒有可存取名稱,而且只有點擊微小的核取方塊像素才有效。產生器將輸入框嵌在 label 內,並放入真實世界的文字,例如 Email notifications 或 Dark mode。整個被標籤的區域都可點擊,控制項也保有對輔助科技有意義的名稱。
此類錯誤還有一個:忘記 label 必須包裹輸入框,或以 id 參照輸入框。在 React 或 Vue 中,當元件有條件地渲染時,label 關聯可能會遺失。請確認 htmlFor 或 for 屬性與輸入框的 id 對應,或像產生器一樣把輸入框嵌在 label 內。
會將旋鈕推出軌道的幾何錯誤
CSS 切換開關基本上就是算術:旋鈕直徑等於軌道高度減去兩倍 padding,而移動距離等於軌道寬度減去軌道高度。一旦這些等式被破壞,就會出錯。
若 padding 相對於軌道高度太大,計算出的旋鈕尺寸會變成零或負值。產生器以純邏輯直接拒絕這種情況——旋鈕尺寸必須保持正值——藉此避免最糟的視覺失敗,也就是完全沒有寬度的旋鈕。
若軌道寬度未比軌道高度至少多 8 像素,旋鈕的開與關位置會重疊。旋鈕看起來只移動幾像素,或在兩種狀態下都待在相同位置。產生器強制寬度減高度的最小值為 8,讓兩個位置保持視覺上的差異。
若 translateX 值被寫死,而後續寬度又改變,旋鈕就會移動錯誤的距離。產生器將移動距離綁定為寬度減高度,因此 CSS 中的像素宣告永遠會對應到當下的尺寸。檢視產生的 CSS 時,你應該會看到移動距離以直接的像素值呈現,而不是藏在框架變數後面。
一個實際算例:軌道寬度 60、軌道高度 32、padding 4 時,旋鈕尺寸為高度減 2 倍 padding,即 32 減 8,等於 24 像素。移動距離為寬度減高度,即 60 減 32,等於 28 像素。padding 4 加旋鈕 24 加移動 28 加 padding 4 等於 60,正好等於軌道寬度,因此旋鈕在兩端都保持相同的 4 像素間距。
產生器的輸入限制值得記住:
| 輸入 | 範圍 | 備註 |
|---|---|---|
| 軌道寬度 | 36–120 像素(整數) | 必須至少為高度 + 8 |
| 軌道高度 | 20–64 像素(整數) | 間接決定旋鈕直徑 |
| 內部 padding | 2–8 像素 | 為旋鈕保留空間 |
| 持續時間 | 0–2000 毫秒 | 0 會停用過場效果 |
| 關、開、旋鈕顏色 | 六位數 HEX | 無效輸入會被拒絕 |
寬度與高度僅接受整數像素。顏色必須是完整的六位數 HEX;像是 #fff 的簡寫形式會在產生任何 CSS 之前,就被純邏輯驗證器拒絕。
對比與狀態辨識失敗的色彩選擇
顏色是大多數手寫切換開關悄悄出錯的地方。開關狀態是二元的——開或關——而無法分辨這兩種狀態的使用者將無法正確使用該控制項。
第一個錯誤是挑選明度過於接近的關閉與開啟顏色。這兩種顏色或許都能在白色卡片上通過視覺審查,但決定使用者判斷哪個狀態啟用的是兩者之間的差異,而不是它們與背景的對比。產生器將顏色選擇留給你,但關、開、旋鈕三個欄位彼此獨立,因此你可以用低對比的關閉色營造停用感,用高對比的開啟色作為確認。
第二個錯誤是旋鈕顏色與軌道顏色之一相同。若旋鈕與關閉軌道同色,關閉位置看起來是空的。若旋鈕與開啟軌道同色,開啟位置看起來像一根實心長條。請挑選與關、開兩者皆對比的旋鈕顏色,讓圓形永遠清晰可見。
第三個錯誤是僅依賴顏色來表示狀態。WCAG 2.2 Success Criterion 1.4.1 規定狀態必須以顏色以外的方式區分。切換開關的開與關通常透過位置(左與右)傳達,已滿足此規則;但若你將相同的開啟色重複用於錯誤狀態或停用狀態,則需要額外提示,例如文字、圖示或不同的邊框。
第四個錯誤是焦點環在強制色彩模式中消失。產生器將 outline-color 設為所選的開啟顏色,這在一般頁面中看起來正確,但在 Windows High Contrast 或強制色彩啟用時可能會消失。原生輸入框在強制色彩模式下保留預設外框,但使用顏色值而非 CanvasText 或 ButtonText 的自訂外框可能會遺失。請以你真實頁面背景(而不只是預覽)驗證焦點可見性,並在檢視關、開、旋鈕顏色彼此間以及與頁面背景的對比時,另行使用 顏色對比檢查工具。
會停用互動的框架整合錯誤
產生器產生的 CSS 與框架無關,但 HTML 與周邊元件程式碼則不然。當片段被放入 React、Vue 或類似的元件模型時,有三個錯誤反覆出現。
第一個是保留 HTML 的 class 屬性不動。React 預期的是 className,雖然會出現執行階段警告,但更關鍵的是 class 並未套用,導致樣式悄悄失效。修正方式很機械:在 React 中將 class 改為 className,其他地方維持 class。input 與 label 的語意關聯應保持不變。
第二個錯誤是受控狀態不對應。若元件以 input checked 搭配 isOn 與 onChange 渲染,但 change 處理器並未更新 isOn,輸入框在瀏覽器中就會變成唯讀。點擊可見的軌道會切換視覺狀態,但按 Space 鍵沒有作用,表單則送原始值。將片段貼入受控元件後,請在實際框架中同時測試點擊與 Space 鍵啟動。
第三個錯誤是破壞 label 與 input 的關聯。在將 label 與 input 作為獨立同層元素渲染的元件中,label 必須以 htmlFor 或 for 與對應的 id 參照輸入框。產生器將 input 嵌在 label 內,關聯會自動成立;若你的框架要求分開的元素,請明確加上配對的 id 與 for。
第四個較隱微的錯誤,是把視覺切換當成設定已儲存的確據。若變更會觸發網路請求,而該請求失敗,UI 顯示為開啟,但伺服器卻記錄為關閉。CSS 片段無法解決此問題。請在視覺層之外處理擱置與失敗狀態,並考慮在更新失敗時將開關回復原狀。
如何在不犯這些錯誤的情況下產生 CSS 切換開關
請依下列步驟產生能挺過原生行為、幾何運算、色彩審查與框架接線的切換開關。
- 開啟 CSS 切換開關產生器,設定軌道寬度、軌道高度、內部 padding 與過場持續時間。請維持在上述限制表格所列的輸入範圍內。
- 挑選關、開、旋鈕顏色。請使用六位數 HEX 值,例如 #cfd8dc、#2563eb 與 #ffffff。確認開與關顏色在明度上有足夠差異以利區分。
- 透過點擊軌道或標籤來切換即時預覽,確認旋鈕能在兩個位置間乾淨移動,不會被裁切或飄出軌道。
- 使用個別的複製按鈕分別複製 CSS 與 HTML。狀態訊息會標示成功複製的輸出;若剪貼簿權限遭拒,可手動選取程式碼。
- 將佔位標籤文字(Enable feature)替換為此開關實際控制的二元設定,例如 Email notifications 或 Dark mode。
- 在目的地頁面或應用程式中,驗證 Space 鍵啟動、Tab 聚焦、實際背景下的焦點環對比、最高 200% 的頁面縮放、強制色彩模式、減少動效,以及產品所需的任何持久化行為。
產生器在基礎片段中並未包含 reduced-motion 媒體查詢,因此若對要求關閉動效的使用者應停用動效,請在目的地的樣式表中加入 prefers-reduced-motion 覆寫。MDN 的 appearance 文件說明了為何 appearance: none 會移除預設的核取方塊繪製,卻保留勾選狀態、聚焦與表單送出。
減少動效、強制色彩與其他模式錯誤
兩種無障礙模式會讓大多數產生的開關元件措手不及。
第一個是 prefers-reduced-motion: reduce。產生器的過場屬於裝飾性質——它會動畫旋鈕在位置之間切換,但不會影響底層狀態。對於偏好減少動效的使用者,請將產生器的過場時間設為 0,或在目的端的樣式表中加入媒體查詢,將 transition-duration 覆寫為 0s。這符合 W3C CSS Basic User Interface 規範在動效並非承載功能時所要求的行為。
第二個是 forced-colors: active,這是 Windows 高對比模式與部分輔助科技所啟用的模式。產生器的焦點外框使用的是所選的「開啟」色彩,也就是一個色彩值。在強制色彩模式下,該色彩可能會被系統調色盤取代,也可能會在符合系統角色時被保留。請在強制色彩模式下測試開關,並確認外框、旋鈕與軌道仍可清楚區分。如果外框消失,請改用系統色彩關鍵字,例如 Highlight 或 ButtonText。
第三個模式錯誤是沒有測試停用狀態。產生器並未提供獨立的停用樣式。如果您的產品需要顯示停用的開關,請在目的端的樣式表中加入 :disabled 樣式,降低不透明度、替換色彩,並禁止指標事件。停用的開關仍應可被輔助科技讀取,因此請將輸入保留在 Tab 順序中,或刻意以 aria-disabled 將其移出。
第四個錯誤是把開關當成一次性動作按鈕。切換元件會持續保存狀態直到使用者變更;按鈕則會觸發事件。如果動作是「提交表單」或「刪除此項目」,那麼開關就是錯誤的控制項,再多的 CSS 也無法讓它正確。請只在使用者可以開關的二進位設定上使用切換元件。
如果您正在權衡選項,修正產生後看起來錯誤的 CSS 三角形對此有詳細說明。
如果您正在權衡選項,在 Mac 上將十六進位轉為 RGB:在瀏覽器中解析任何 CSS 十六進位值對此有詳細說明。