CSS 切換開關產生器透過兩組公式來設定每個開關的尺寸:旋鈕直徑等於軌道高度減去兩倍內距,而勾選時的移動距離等於軌道寬度減去軌道高度。當渲染出的預覽與您預期的不同時,原因幾乎一定是下列三種之一——輸入值有效但產生不平衡的比例、三種顏色中有兩種在視覺上互相衝突,或是過渡效果掩蓋了狀態的改變。三個具體的調整就能修正大多數「結果看起來損壞」的回報:調整軌道寬度與高度,使寬度至少大於高度 8 像素;提高內距,讓旋鈕在軌道內有足夠空間;或在動畫造成問題時將持續時間設為零。產生器會先用邏輯拒絕無效的組合,避免出現負數尺寸或旋鈕超出軌道的情況,這代表每個能正常運作的預覽都已經符合幾何規則。由於公式與範圍都顯示在產生的 CSS 內,修正錯誤結果只需要重新開啟 CSS 切換開關產生器,調整少數幾個值即可,而不必重寫整份樣式表。本文的其餘部分將逐步說明每個輸入項控制什麼、哪些徵兆對應哪些原因,以及當預覽第一次回傳不理想時的調整順序。

how do i fix a result that looks wrong after i generate css toggle switch
修正產生 CSS 切換開關後出現的錯誤結果

產生器接受哪些輸入,以及為何輸入很重要

CSS 切換開關產生器接受五個輸入——軌道寬度、軌道高度、內距、過渡持續時間,以及三組六位數的 HEX 顏色——並會產生同步的 CSS 與無障礙 HTML,包裝在一個真正的原生 checkbox 上。螢幕上看到的每個預覽都遵循同一組限制,因此理解範圍是診斷錯誤結果的第一步。

輸入項接受範圍強制規則
軌道寬度36–120 px整數像素;寬度必須至少大於高度 8 px
軌道高度20–64 px僅限整數像素
內距2–8 px必須在軌道內保留一個正值大小的旋鈕
過渡持續時間0–2000 ms僅限整數毫秒
關、開與旋鈕顏色六位數 HEX格式如 #1A2B3C;無效字串會被拒絕

產生器將旋鈕大小計算為高度減去兩倍內距,因此旋鈕永遠不會是負值,也不會大於軌道。它將移動距離計算為寬度減去高度,這就是為什麼存在「寬度至少大於高度 8 像素」這條規則——任何小於此差距的值都會讓開與關的位置被壓扁,直到開關看起來像一個靜止的藥丸形狀。如果您的預覽違反了這些規則之一,則輸入會在預覽渲染前就被拒絕,問題出在其他地方。

修正尺寸與幾何問題

尺寸錯誤通常以三種方式呈現:旋鈕在一側超出軌道、開與關的位置重疊在一起,或是開關看起來像一個扁平的藥丸而看不到明顯的動作。每個徵兆都對應到三個尺寸輸入項之一。

如果旋鈕在一端看起來被裁切,代表內距對於所選的高度來說太小。旋鈕直徑等於高度減去兩倍內距,因此高度 30 px、內距 2 px 的軌道會產生 26 px 的旋鈕,而同樣的軌道搭配內距 14 px(超出允許的 2–8 範圍)則會產生 2 px 的旋鈕。修正方法是將內距往允許範圍的上半段提高,讓旋鈕在兩側都有明顯的邊距。反過來說,高度 20 px 搭配內距 8 px 只會留下 4 px 的旋鈕,雖然技術上有效,但視覺上太小,無法辨識為開關——這時就應該提高軌道高度。

如果開與關的位置看起來一樣,代表寬度與高度過於接近。移動距離等於寬度減去高度,因此寬度 50 px、高度 48 px 只會產生 2 px 的移動距離——在合理的顯示比例下根本看不見。工具強制規定最小 8 px 差距正是基於這個原因。在 48 px 的軌道上將寬度提高到至少 64 px,即可恢復可見的移動效果。

一個以寬度 72、高度 36、內距 6 為例的計算過程如下:

  • 旋鈕大小 = 36 − (2 × 6) = 24 px
  • 移動距離 = 72 − 36 = 36 px
  • 未勾選位置:旋鈕左緣位於 6 px(即所選的內距)
  • 勾選位置:旋鈕左緣位於 6 + 36 = 42 px,右緣位於 42 + 24 = 66 px(= 寬度 − 內距)

兩端會出現相同的內距,是因為「內距 + 旋鈕 + 移動距離」可化簡為「寬度 − 內距」。如果您的預覽沒有產生這種對稱性,代表三個數字中有某個被四捨五入或以不同於公式假設的方式解讀。

修正顏色與對比問題

顏色錯誤有三種類型:關與開的軌道顏色過於相似而無法區分;旋鈕顏色與兩種軌道顏色融合在一起;或是焦點環在頁面背景上消失不見。產生器只要求六位數的 HEX 值,所以任何兩個視覺上不同的色碼都會通過驗證——它無法分辨 #1B6B4D 和 #1B6E4E 看起來其實是同一種顏色。

首先,將關與開的顏色並排檢視。如果不閱讀勾選狀態就無法一眼分辨,就拉開明度差距或調整色相,讓兩種軌道顏色達到 AA 等級的明度對比。旋鈕顏色應與兩種軌道都形成對比;淺色軌道上的白色旋鈕或深色軌道上的黑色旋鈕,都是常見的失敗模式。

焦點環是透過原生 focus-visible outline 以開啟狀態的顏色繪製。這個環位於軌道的偏移位置而非直接重疊其上,這代表它可能會在目標頁面上被背景吃掉。如果在預覽中看不到它,請對照實際的頁面背景來驗證,而非白色預覽面板。一個在獨立環境下很顯眼的顏色,在帶有底色的 body 背景上可能會完全消失。如果開啟顏色因為品牌形象而必須固定,可以考慮在目標樣式表中加入外層 outline,而不要更動輸入值。

修正過渡與動畫問題

過渡問題的表現是:開關切換時沒有動畫、動畫快到無法看清,或在使用者偏好減少動畫時仍然播放動畫。工具以毫秒為單位顯示持續時間,因此修正方式很直接:提高持續時間以減慢動畫,或將持續時間設為零以完全移除插值效果而不改變狀態。

將持續時間設為零是驗證動畫是否為問題來源的最簡單方法。如果關閉動畫後結果看起來仍然不對,那問題就在於幾何或顏色,而非時間。將持續時間恢復到可讀的值——對於這種小型開關通常介於 150 到 300 ms 之間——即可在不更動其他輸入的情況下讓動畫恢復。

複製出來的基準程式碼並未包含 reduced-motion 媒體查詢。如果動畫僅是裝飾性質,或使用者已要求減少動畫,請在目標樣式表中將 transition-duration 覆寫為零,而不要重新產生。《產生 CSS 切換開關時應避免的錯誤》指南深入探討了這個議題與相關陷阱,而 《從產生的 CSS 切換開關中移除過渡效果》指南則詳細說明具體的覆寫方式。

逐步檢視錯誤結果

下次預覽結果出錯時,請依此順序操作。每一步都會先隔離單一變數再進入下一步,這樣就不會同時處理多個原因。

  1. 使用目前的值開啟 CSS 切換開關產生器,一邊點擊軌道與標籤,一邊觀察預覽結果。
  2. 將持續時間設為零,確認在沒有動畫的情況下,開與關的位置在視覺上仍然可以區分。如果兩者疊在一起,代表寬度與高度的差距太小;提高寬度,使寬度至少大於高度 8 px。
  3. 檢查旋鈕在軌道兩端的位置。如果旋鈕觸碰到邊緣或超出邊緣,將內距往 2–8 px 範圍的上半段提高,或提高軌道高度,使旋鈕大到足以辨識為開關。
  4. 恢復合理的持續時間(約 200 ms),再次切換預覽。確認旋鈕在兩個位置之間平滑移動,且兩側的內距相同。
  5. 比較關、開與旋鈕的顏色。將任何一組難以一眼分辨的顏色替換掉,並保持三者皆為六位數 HEX 值。
  6. 按下 Tab 鍵讓開關取得焦點,確認焦點環在目標頁面背景上仍然可見。如果消失了,請提高開啟顏色的對比,或在目標樣式表中加入外層 outline。
  7. 複製 CSS 與 HTML,將範例標籤替換為實際的二元設定,例如「電子郵件通知」或「深色模式」,然後確認空白鍵可切換狀態,且整個標籤區域都可點擊。

出貨前再次檢查無障礙性

產生器保留原生 input 元素,這代表只要不更動周圍的標記,鍵盤啟動、焦點與表單提交功能都會持續運作。當視覺上看起來正確,但在實際環境中卻出現異常時,原因幾乎都在下游,而非產生器本身。

測試 Tab 鍵是否可到達開關,以及空白鍵是否能切換狀態。如果您使用 React、Vue 或其他框架,請再次確認受控狀態的接線沒有阻擋原生的 checked 與 change 處理常式——不一致可能會讓視覺上的開關承諾了一個永遠不會保存的變更。MDN 上 appearance 屬性的說明文件確認,CSS 中的 appearance: none 會移除預設繪製,但保留原生語意。

最後,請確認開與關的區分不只是依賴顏色,特別是在周圍文字無法讓狀態一目了然時。在後果重要的情境下加入明確的狀態文字,並在您的產品樣式表中驗證 disabled、invalid、loading 與 read-only 的呈現方式——產生器並未包含這些。