TailwindCSS 元件庫比較:daisyUI、Flowbite、Preline 怎麼選 | TailwindCSS 完整教學
上一篇我們把
cn()、cva這些最佳實踐工具鏈織成了現代元件的骨架。這一篇往上一層:當你不想每個 Button、Modal 都從零刻起,元件庫(Component Libraries) 就是別人已經替你組好、可以直接取用的成品。但市面上光是「有樣式」的 TailwindCSS 元件庫就有好幾套——官方付費的 Tailwind Plus、純 CSS 的 daisyUI、帶互動的 Flowbite 與 Preline。它們定位不同、取捨不同,選錯了地基,後面會很痛。這篇帶你把它們一次比清楚。
前言
所謂元件庫(Component Library),就是一組「已經寫好、可重複取用」的 UI 元件集合——按鈕、卡片、對話框、下拉選單、表格等等,你不必自己從 utility 一個個拼,而是引入現成的樣式或元件直接用。它把上一篇談的 cva + cn() 骨架,規模化成一整套經過設計、彼此風格一致的成品。
先用一個生活化的類比建立心智模型。用元件庫就像裝潢新家時買「系統櫃」而非「請木工現場訂做」:系統櫃(元件庫)已經做好、尺寸標準、顏色成套,搬回家組一組就能用,速度快、風險低,代價是樣式受限於廠商提供的款式;木工訂做(自己用 Tailwind 刻)則完全照你的想法,獨一無二,但慢、貴、且吃師傅功力。而本篇要比較的四套元件庫,就像四家不同定位的系統櫃品牌:有主打「便宜好裝」的(daisyUI)、有「功能齊全帶電動五金」的(Flowbite、Preline)、也有「設計師聯名高端款」的(Tailwind Plus)。
本系列以 TailwindCSS v4 為預設版本。本篇你將學到:
- 四套主流「有樣式」元件庫的定位:Tailwind Plus、daisyUI、Flowbite、Preline 各自解決什麼問題、適合誰
- 一張比較表看懂取捨:授權、框架支援、整合方式、v4 相容性一目了然
- 實際動手:daisyUI 的安裝與語意化 class、Flowbite 元件的用法示範
- 兩大坑:樣式覆寫的優先權問題、以及「被元件庫鎖定」的風險與對策
本系列以 TailwindCSS v4 為預設版本,範例皆以 v4 語法示範。凡涉及 v3 差異之處,我會特別標註。
核心概念
什麼是「有樣式」vs「無樣式」元件庫
在比較個別方案之前,得先建立整個生態最重要的一條分野:有樣式(styled) 與 無樣式(headless / unstyled)。
有樣式元件庫直接給你「配好視覺的成品」——顏色、圓角、間距、陰影、hover 效果全都預設好了,你加一個 class 或引入一個元件,畫面立刻就有模有樣。本篇的四位主角(Tailwind Plus、daisyUI、Flowbite、Preline)全屬此類。優點是快,缺點是外觀受制於它的預設,要改成品牌獨有的樣子得花力氣對抗預設值。
無樣式元件庫(如 Headless UI、Radix UI)則只提供「行為與無障礙邏輯」——例如 Dropdown 的開關狀態、鍵盤導覽、焦點管理、正確的 ARIA 屬性——但完全不給你任何視覺樣式,長相百分之百交給你用 Tailwind 自己刷。優點是完全掌控外觀,缺點是要自己寫樣式、上手較慢。這是下一篇的主題,本篇先聚焦「有樣式」這一側。
四套元件庫比較對照表
先用一張表建立全景,再逐一拆解。這四套是「有樣式」陣營裡最主流的選擇:
| 元件庫 | 定位 | 授權 | 整合方式 | 互動性 | 框架 | v4 相容 |
|---|---|---|---|---|---|---|
| Tailwind Plus | 官方最高品質、加速產品組裝 | 付費(買斷,終身存取) | 複製貼上 | Headless UI / 官方 Elements | React / Vue / 原生 HTML | 官方維護,跟進 v4 |
| daisyUI | 最快上手、純 CSS 語意化 class | 免費(MIT) | Tailwind plugin | 幾乎純 CSS(部分靠原生 HTML) | 任意(含無框架) | daisyUI 5 專為 v4 打造 |
| Flowbite | 帶互動 JS 的完整元件集 | 免費基礎 + 付費 Pro | npm / CDN | 內建 JS,有 flowbite-react/vue | React / Vue / 原生 HTML | 支援(留意版本對應) |
| Preline | 大量精緻 HTML 元件 | 免費(MIT) | npm / CDN | 需引入 Preline JS 初始化 | 原生 HTML 為主 | 支援(留意版本對應) |
這張表的關鍵是理解每一欄背後的取捨。「整合方式」決定了你怎麼把它放進專案:複製貼上(Tailwind Plus)代表程式碼進到你的 repo、你完全擁有它,沒有 runtime 依賴、bundle 幾乎零負擔,但更新要手動;Tailwind plugin(daisyUI)代表它以 CSS 形式織進你的樣式層,一個 @plugin 就生效;npm / CDN(Flowbite、Preline)代表你安裝一個套件、引入它的 JS 來驅動互動元件。「授權」則直接關係到成本與商用限制——daisyUI 與 Preline 是 MIT 免費,Flowbite 有免費核心與付費 Pro,而 Tailwind Plus 是官方付費買斷。
還有一個常被忽略、卻很關鍵的欄位是「互動性」。UI 元件大致分兩種:一種是純視覺的(按鈕、卡片、徽章),只要有樣式就完整;另一種是帶狀態的(Modal 的開關、Dropdown 的展開、Tabs 的切換、Datepicker 的日期選取),需要 JavaScript 去管理它們的開關與焦點。這條線正好把四套元件庫切成兩派:daisyUI 走「盡量純 CSS」路線,連 Modal 都用原生 <dialog> 免掉 JS,好處是零 runtime、壞處是複雜互動元件較少;Flowbite、Preline 則坦然引入自家 JS 來驅動這些帶狀態的元件,元件更齊全,代價是多一份 JS 負擔;Tailwind Plus 則把互動交給官方的 Headless UI 或 Elements。理解這條線,你才不會期待「純 CSS 的 daisyUI 能給你一個功能完整的 Datepicker」——那本來就不是它的守備範圍。
逐一拆解:各自的定位與優缺點
Tailwind Plus(官方付費,前身 Tailwind UI)。由 Tailwind CSS 原作者團隊打造,是「複製貼上」型的元件與模板庫。它同時提供 React、Vue、原生 HTML 三種版本,互動性由官方的 Headless UI(React/Vue)或官方 Elements(HTML 版無頭元件)驅動。內容涵蓋 Marketing(行銷頁)、Application UI(後台)、Ecommerce(電商)等大量 UI Blocks 與完整頁面模板。優點是設計品質最高(官方水準)、無 runtime 依賴、bundle 幾乎零負擔;缺點是需付費、且元件要手動複製進專案。適合預算充足、想跳過設計環節直接組裝高品質產品的團隊。
daisyUI(免費,純 CSS)。最受歡迎的免費 Tailwind 元件庫,以 Tailwind plugin 形式運作,在 utility 之上新增語意化 class(btn、card、badge、modal…)。它幾乎不依賴 JavaScript,連 Modal 都能用原生 <dialog> 做到純 CSS 互動。優點:上手最快、內建數十套主題、可用於任何框架甚至無框架、bundle 很小;缺點:設計風格較統一(容易「一看就是 daisyUI」)、複雜互動元件較少。daisyUI 5 專為 Tailwind v4 打造,直接用 v4 的 @plugin 語法引入。
Flowbite(免費基礎 + 付費 Pro)。提供帶互動 JavaScript 的完整元件集,涵蓋 Modal、Dropdown、Datepicker、Tooltip 等需要 JS 的元件,並提供 flowbite-react、flowbite-vue 等官方框架綁定。優點:元件多、有官方 React/Vue 整合、文件完整;缺點:引入 JS 會增加 bundle、React 版元件的客製有時受 props 限制。適合需要現成互動元件、又用 React/Vue 的專案。
Preline(免費,MIT)。提供 300+ 精緻的 HTML 元件,互動由一支 Preline JS 驅動(需在專案裡引入初始化)。優點:元件數量多、設計感佳、原生 HTML 到處可用;缺點:互動綁定它自己的 JS 與 hs- 前綴 class,較吃它的慣例。適合以原生 HTML(或非 React 框架)為主、想要大量現成精緻區塊的專案。
選型建議
把上面的取捨收斂成一句話決策:
- 要最快、不綁框架、免費 → daisyUI(加個
btn就有樣式) - 用 React/Vue、要現成互動元件 → Flowbite(官方框架綁定最省事)
- 純 HTML、要大量精緻區塊 → Preline(元件多、設計感強)
- 官方最高品質、預算足、想複製貼上跳過設計 → Tailwind Plus(付費買斷)
要提醒的是,這四選一並非「一輩子只能選一個」。實務上常見的組合,是以一套當主力鋪底、再局部借另一套補強——例如用 daisyUI 快速鋪好整站基礎樣式與主題,再單獨引入 Flowbite 的 Datepicker 補上它缺的複雜互動;或是先用免費方案做出可用的原型驗證產品方向,等專案進入需要「設計質感拉滿」的階段,再評估是否值得付費升級到 Tailwind Plus。選型的重點從來不是「哪一套最強」,而是「以你此刻的專案階段(原型 / MVP / 正式產品)、團隊技術棧(React / Vue / 純 HTML)、預算與對外觀獨特性的要求,哪一套的取捨最貼合」。同一個團隊在不同專案、甚至同一專案的不同階段,合理的答案都可能不同。
關鍵術語
- 有樣式元件庫(Styled):直接提供配好視覺的成品外觀,加 class 或引入元件即可用。本篇四位主角皆屬此類。
- 語意化 class:如 daisyUI 的
btn、card——用「元件語意」命名的 class,和 Tailwind 的原子 utility(px-4)分屬不同命名空間,可混用。 - 複製貼上(Copy-paste):如 Tailwind Plus——元件程式碼直接進你的 repo,你完全擁有、無 runtime 依賴,代價是手動更新。
- 鎖定(Lock-in):當專案深度綁定某元件庫的 class 慣例或 API,日後要抽換成本很高的風險。
實作範例
理論看完,動手把最具代表性的兩套(免費、跨框架的 daisyUI,以及帶互動、React 導向的 Flowbite)實際跑一次。
範例一:daisyUI 安裝與按鈕(純 CSS,v4)
daisyUI 5 在 v4 底下的安裝非常乾淨——裝一個 npm 套件,再在你的主 CSS 用 @plugin 引入即可,不需要 tailwind.config.js:
# 安裝 daisyUI
npm install -D daisyui
/* app.css:Tailwind v4 + daisyUI,一次搞定 */
@import "tailwindcss";
@plugin "daisyui";
/* 需要指定主題時,可帶參數 */
@plugin "daisyui" {
themes: light --default, dark --prefersdark, cupcake;
}
引入後,你就能用語意化 class 寫元件。重點在於 daisyUI 的 class 和 Tailwind utility 可以自由混用:
<!-- btn / btn-primary 來自 daisyUI;w-full / mt-4 來自 Tailwind -->
<button class="btn btn-primary">主要按鈕</button>
<button class="btn btn-outline btn-secondary">外框按鈕</button>
<button class="btn btn-primary w-full mt-4">滿版按鈕</button>
<!-- 對照:同一顆按鈕若用純 Tailwind,要寫這麼長 -->
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg
hover:bg-blue-700 focus:ring-2 focus:ring-blue-500">
主要按鈕
</button>
daisyUI 最迷人的地方之一是主題系統——切換整站配色只需改一個 data-theme 屬性,不必動任何 class:
<!-- 全站主題:改 <html> 的 data-theme 即可 -->
<html data-theme="cupcake"> <!-- 粉色主題 -->
<!-- 局部主題:只影響這個容器內的子元素 -->
<div data-theme="dark" class="p-8 rounded-box">
<button class="btn btn-primary">這顆按鈕會套用深色主題</button>
</div>
連 Modal 都能做到純 CSS、零 JavaScript——靠原生 <dialog> 元素:
<!-- 純 CSS Modal:用原生 dialog,不需任何 JS 框架 -->
<button class="btn" onclick="my_modal.showModal()">開啟 Modal</button>
<dialog id="my_modal" class="modal">
<div class="modal-box">
<h3 class="text-lg font-bold">提示</h3>
<p class="py-4">按 ESC 或點下方按鈕關閉。</p>
<div class="modal-action">
<form method="dialog">
<button class="btn">關閉</button>
</form>
</div>
</div>
</dialog>
範例二:Flowbite 元件用法(帶互動,React)
Flowbite 的定位剛好補上 daisyUI 較少的「複雜互動元件」。原生 HTML 版本安裝後需引入它的 JS 來驅動互動:
# 原生 HTML 版:安裝核心
npm install flowbite
# React 版:官方框架綁定
npm install flowbite-react
原生 HTML 版靠 data- 屬性宣告互動,再由 Flowbite JS 接手,完全不必寫 JavaScript:
<!-- 引入 Flowbite JS(或用打包工具 import) -->
<script src="node_modules/flowbite/dist/flowbite.min.js"></script>
<!-- Dropdown:用 data-dropdown-toggle 宣告觸發目標 -->
<button data-dropdown-toggle="menu"
class="text-white bg-blue-700 hover:bg-blue-800 rounded-lg px-4 py-2">
選單
</button>
<div id="menu" class="hidden bg-white rounded-lg shadow w-44">
<ul class="py-2 text-sm text-gray-700">
<li><a href="#" class="block px-4 py-2 hover:bg-gray-100">個人資料</a></li>
<li><a href="#" class="block px-4 py-2 hover:bg-gray-100">設定</a></li>
</ul>
</div>
React 專案則直接用 flowbite-react 元件,以 props 控制狀態,寫起來就是一般 React:
// FlowbiteDemo.tsx:用 React 元件驅動 Modal
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from "flowbite-react";
import { useState } from "react";
export function FlowbiteDemo() {
const [open, setOpen] = useState(false);
return (
<>
<Button color="blue" onClick={() => setOpen(true)}>
開啟 Modal
</Button>
<Modal show={open} onClose={() => setOpen(false)}>
<ModalHeader>Modal 標題</ModalHeader>
<ModalBody>
<p className="text-gray-500">這是由 flowbite-react 驅動的對話框內容。</p>
</ModalBody>
<ModalFooter>
<Button onClick={() => setOpen(false)}>確認</Button>
<Button color="gray" onClick={() => setOpen(false)}>
取消
</Button>
</ModalFooter>
</Modal>
</>
);
}
對照這兩個範例,你能清楚感受到差異:daisyUI 是「加 class、幾乎零 JS」,適合快速鋪畫面;Flowbite 是「引入 JS 或 React 元件」,換來 Modal、Dropdown、Datepicker 這類需要狀態管理的互動元件。實務上,兩者甚至可以在同一專案裡分工——用 daisyUI 鋪基礎樣式,用 Flowbite 補複雜互動。
順帶一提 Preline 的使用手感:它介於兩者之間,元件是純 HTML(所以到處可用),但互動靠一支 Preline JS 驅動,而且它的互動元件慣用 hs- 前綴的 class(如 hs-accordion、hs-accordion-toggle)來標記結構與狀態。你在專案入口引入並初始化 Preline JS 後,這些帶前綴的 class 就會被接管、產生展開收合等行為。它的強項是「元件數量多、設計精緻」,適合以原生 HTML 或非 React 框架(如純 Astro、傳統伺服器渲染頁面)為主、又想要大量現成漂亮區塊的專案。心智上可以這樣記:daisyUI 是「語意化 class 換樣式」、Flowbite 是「元件/JS 換互動」、Preline 是「HTML 片段 + hs- class 換精緻互動區塊」。
常見錯誤與最佳實踐
坑一:樣式覆寫的優先權(蓋不掉的預設值)
最常見的挫折,是想用 Tailwind utility 蓋掉元件庫的預設樣式,卻蓋不動。例如你想把 daisyUI 的 btn 圓角改掉:
<!-- ❌ 有時失效:btn 已內建 rounded,rounded-none 不一定蓋得掉 -->
<button class="btn btn-primary rounded-none">按鈕</button>
原因和上一篇《最佳實踐》講的一樣:Tailwind 所有 utility 特異性相同,誰勝出取決於 CSS 生成順序,而元件庫的樣式有時是在你的 utility 之後生成、或帶了更高特異性的選擇器,於是你的 rounded-none 打不過它。
正確做法有幾種,依情況選用:
<!-- ✅ 用 ! 前綴強制提高優先權(v4 的 important 修飾) -->
<button class="btn btn-primary !rounded-none">按鈕</button>
/* ✅ 或在 CSS 層改該元件庫提供的 CSS 變數 / 主題 token,治本而非硬蓋 */
@plugin "daisyui" {
themes: [{ mytheme: { "--rounded-btn": "0"; } }];
}
原則是:能透過元件庫官方的主題 token / CSS 變數調整,就別硬用 utility 蓋——前者是它設計好的「客製入口」,穩定且不會打架;!important 是最後手段,零星微調可用,但整片濫用會讓樣式難以維護。
坑二:被元件庫「鎖定」的風險
第二個要提早警覺的,是鎖定(lock-in):當你的 markup 深度綁定某元件庫的 class 慣例(daisyUI 的 btn、Preline 的 hs-accordion)或 React API(flowbite-react 的元件),日後想抽換成本會很高——因為這些 class 與 API 散落在整個 codebase。
這不代表「不該用元件庫」,而是要有意識地控制暴露面:
- 把元件庫包在你自己的元件裡。例如做一個你自己的
<Button>,內部才用 daisyUI 的btn或 flowbite-react——上一篇的cn()+cva骨架正好派上用場。這樣全站只在「一處」依賴元件庫,日後要換,只改這一處。 - 偏好 class-based / HTML-based 而非深度 API 綁定。daisyUI 這種「只是 CSS class」的方案,抽換相對容易(改 class 就好);深度綁定框架元件 API 的方案,遷移成本較高。
- 善用主題 token 而非寫死顏色。把品牌色定義在主題層,元件引用 token,換元件庫時樣式意圖還在。
最佳實踐小結
- 選型先問兩題:要不要付費/官方品質?用不用 React?——答案幾乎就決定了四選一。
- 能用主題 token 客製,就別硬用 utility 蓋;
!important留給零星微調。 - 用自己的元件包住元件庫,把依賴收斂到一處,降低鎖定風險。
- 確認 v4 相容:daisyUI 用第 5 版、Flowbite/Preline 留意版本對應、Tailwind Plus 由官方維護跟進。
小結
這是 TailwindCSS 完整教學 系列的第二十九篇。上一篇 《最佳實踐》 我們把 cn()、cva、clsx 這些工具鏈織成現代元件的骨架;而這一篇,我們把視角拉高一層,認識了以這套骨架為地基、別人已經替你組好的「有樣式元件庫」。回顧幾個重點:
- 四套主流有樣式元件庫:Tailwind Plus(官方付費、複製貼上、品質最高)、daisyUI(免費、純 CSS 語意化 class、最快上手)、Flowbite(帶互動 JS、有 React/Vue 綁定)、Preline(大量精緻 HTML 元件)。
- 選型兩題定生死:要不要付費/官方品質?用不用 React?——快用 daisyUI、React 用 Flowbite、純 HTML 精緻選 Preline、官方買斷選 Tailwind Plus。
- v4 相容:daisyUI 5 專為 v4 打造、直接用
@plugin;Flowbite/Preline 留意版本對應;Tailwind Plus 由官方跟進。 - 兩大坑:樣式覆寫的優先權(善用主題 token,
!important是最後手段)、被元件庫鎖定的風險(用自己的元件包住、把依賴收斂到一處)。
有樣式元件庫給你速度,代價是外觀受制於它的預設。但如果你要做的是有強烈品牌識別、外觀完全自訂的產品呢?那就需要另一種思路——只借「行為與無障礙邏輯」、視覺自己刷。下一篇 《無樣式元件庫》 就要帶你認識 Headless UI、Radix UI 這類 headless 方案,看看如何在「完全掌控外觀」與「不重造無障礙輪子」之間取得最佳平衡。