同一個 CSS bug 出貨了三次,因為修好一次沒有修好那個比例
一個圓角膠囊卡在另一個圓角容器裡,兩條曲線之間需要真正的間距,不然內層形狀會明顯戳出外層邊框。修過一次、又在別處修過一次,結果在同一個已經修好過的元件的新尺寸變體裡,又出貨了第三次。
背景
bopomofokids.com 整個視覺風格是一套刻意設計的系統
——每個元素都有粗粗的墨色邊框、硬邊偏移陰影,完全不用模糊。按鈕跟膠囊一律是
完全圓角(rounded-full)。這套系統裡有一個一再出現的元件:分段控制項——一個
rounded-full 的彩色膠囊代表目前選中的選項,滑動在另一個更大的 rounded-full
容器裡——用在頁首的語言切換、設定面板的各種開關,以及某個模式自己的遊戲內速度
切換器上。
這個模式有一個從 class name 看不出來的幾何問題,只有真的去看渲染結果才會發現。
為什麼兩層完全圓角需要真正的間距
這不是一個可以設一次就一勞永逸的固定像素值——它是外層 padding 跟內層膠囊實際 渲染高度之間的一個比例,而膠囊的渲染高度又取決於字級、行高,以及標籤文字 本身需要多少空間。
前兩次
這個 bug 分別獨立在兩個不同的元件裡出貨:頁首/設定面板用的 Segmented 元件
(當時是 p-1),以及 BalloonMode 自己的遊戲內速度切換器(當時是 p-1.5)。
兩者都用同一種方式修好——加大 padding——分別落在 p-1.5 跟 p-2。兩個不同的
元件、兩次獨立的修法,但根本原因是同一個。
第三次——發生在一個已經修好過的元件裡
Segmented 後來為了頁首更精簡的切換介面,新增了 sm 跟 xs 兩個尺寸變體,是
2026-07-20 那次版面重新設計的一部分。這兩個新變體都複製了已經修好的 md 變體
的邊框寬度,但 padding 卻退回了 p-1:
const SIZES = {
md: { box: 'border-3 p-1.5 gap-1', option: 'px-2.5 py-1.5 text-xs' },
sm: { box: 'border-3 p-1 gap-1', option: 'px-2 py-1 text-[11px]' }, // ← 同一個 bug,又回來了
xs: { box: 'border-2 p-1 gap-0.5', option: 'px-1.5 py-0.5 text-[10px]' }, // ← 同一個 bug,又回來了
};
App.tsx — Segmented 尺寸變體,第三次修法之前
同一個元件、同一個邊框寬度、md 尺寸已經出貨過一次的修法——結果一模一樣的 bug
又在兩個新尺寸變體裡重現了一次,因為已經上線的那次修法,只動到了當時存在的那
一個尺寸變體。這次是隔天就被使用者的一張語言切換介面截圖抓到,修法也一樣:
把兩個新變體的 padding 從 p-1 加到 p-1.5。
const SIZES = {
md: { box: 'border-3 p-1.5 gap-1', option: 'px-2.5 py-1.5 text-xs' },
sm: { box: 'border-3 p-1.5 gap-1', option: 'px-2 py-1 text-[11px]' },
xs: { box: 'border-2 p-1.5 gap-0.5', option: 'px-1.5 py-0.5 text-[10px]' },
};
App.tsx — Segmented 尺寸變體,第三次修法之後
為什麼英文標籤讓情況更糟
這個 App 的語言切換可以顯示「中文|EN」,或是切到英文介面文案時的對應版本,而 英文標籤通常比旁邊的中文更高更寬——同樣的視覺份量需要更多行高。這在完全沒有 改動任何 padding 數值的情況下,進一步壓縮了實際間距:同一組數字 padding,一旦 膠囊裡的標籤需要更多垂直空間,實際留下的空隙就變少了。一個在中文下隨便一瞄 沒事的控制項,在完全相同的 CSS 數值下,切到英文可能就出事。
這次學到什麼
修好 Segmented 的 md 變體,並沒有修好 Segmented——它只修好了一個特定的
邊框寬度對 padding 比例。sm 跟 xs 實質上是恰好共用一個名字跟一個檔案的
新元件。每一個巢狀膠囊控制項的新尺寸變體,都需要自己的間距檢查;在同一個檔案
裡別處錯過一次,不代表新的變體就對這個問題免疫。
同一個 padding 數值,渲染出來的實際間距會因為膠囊裡標籤需要多高而不同——這又 取決於語言、字型、文字長度。一個在某種語言的文案下看起來沒事的控制項,在真的 檢查過它實際上會出貨的每一種語言之前,都不算證明沒事。
光讀 Tailwind 的 class,p-1 跟 p-1.5 看起來都不像明顯有問題——這個 bug 只
存在於渲染出來的幾何裡。新增或調整任何巢狀膠囊控制項時,真正能抓到這個問題的
做法,是對實際輸出、以它真正的像素尺寸截圖(而不是在開發伺服器上 100% 縮放
隨便看一眼),而且這件事要對每一個新變體都做一次,不是對整個元件做一次就算數。