本篇文章更新時間:2026/01/21
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
內容目錄
Shadcn Radio Button,從一行 HTML 變成百行依賴:我讀完後的三個啟發
編輯前言:這篇文章來自 The Incredible Overcomplexity of the Shadcn Radio Button,作者從一個簡單的 UI 任務出發,意外挖出前端生態系中「過度工程化」的現象。讀完之後我不得不重新思考:我們究竟是提升效率,還是讓事情變得不必要地複雜。
核心觀點 (Key Takeaways)
- React UI 生態系逐漸習慣「重寫原生元件」,導致極端複雜化。
- Radix + Shadcn 層層堆疊,最後只是為了做一個原本 HTML 已經完美支援的 radio button。
- CSS 其實已經能輕鬆客製化 radio button,不需要 ARIA hack、不需要 JS、不需要第三方 SVG icon。
深入解析
作者一開始只想更新 radio button 的視覺樣式,原本以為就是:
結果一查程式碼,發現團隊用的是 Shadcn 的 與 。問題是,Shadcn 本身不是原生套件,而是把元件複製到你的 codebase 裡。然而這些元件的底層又依賴另一套:Radix。
換句話說,為了渲染一個 radio button,你需要:
- Shadcn 的封裝
- Radix 的 primitives
- Lucide 的 circle icon
- 30+ 條 Tailwind class
- 一堆 React 元件與 ARIA 屬性
1. Radix:原來你不是 UI 套件,而是「更底層的 UI 套件」
作者點出 Radix 的定位:它提供的是「低階可組合元件」,而非直接可用的 UI。Shadcn 再把 Radix 包起來並提供樣式。結果就是兩層 abstraction 疊在一起。
Radix 還做了一件很奇怪的事:
它不是用
,而是用加 ARIA 去假裝成 radio。
這直接違反了 WAI-ARIA 的第一條規則:
如果原生 HTML 能做,就不要用 ARIA 模擬。
2. 原生 radio 其實早就能自由客製化了
作者列出 CSS 技巧,證明這不用元件、不用 JS、不用第三方 icon:
appearance: none移除預設樣式- 使用
::before畫出 dot - 用
:checked::before控制顯示 - 加上
border-radius: 50%完成圓形
這些都是普通 CSS 能做到的。重點是:
Shadcn 的 radio button 至少包含「30 個 Tailwind class」,還需要一堆 JS,而純 CSS 解法反而更簡單。
3. 現代前端其實常常「把簡單的東西變難」
作者後面提出他真正的擔憂:
- 小元件的過度封裝會產生巨大心智負擔
- JS 體積變大、效能變差
- 新手難以理解一個應該簡單的 UI 控制元素
最後他引用那句令人苦笑的結語:
We have strayed so far from the light.
並放上一行乾淨明亮的 HTML:
筆者心得與啟發
讀完這篇文章,我最大的感觸是:前端生態系其實被自己創造的複雜性困住了。尤其在 React 文化裡,我們習慣看到 UI 就想「componentize」,但忘了 HTML 已經提供了許多強大的內建元件。
這篇文章提醒我三件事:
- 不要為了 abstraction 而 abstraction。如果原生 HTML 已經很好用,就不要重造輪子。
- 工具應該降低複雜度,而不是添加更多依賴。工程師本來就已經有很多事情要理解,不該為了一個 radio button 多讀上百行 React code。
- 效能與可維護性來自選擇最簡單的方案。簡單的 HTML + CSS,往往比框架套框架更強大。
在實務上,我會更留意自己是否因為「框架思維」而忽略了 HTML/CSS 本身的能力。或許下一次遇到 UI 客製化,我會先問自己:
瀏覽器其實已經提供我需要的工具了嗎?
這篇文章是一次很好、也有點幽默的提醒:有時候,我們只需要一個 。
