tailwind 快速上手筆記

最近有機會在新專案試用 tailwind。而為了避免繞遠路,在正式開工前先花了點時間搜集關於這個套件的 best practice。

注意此篇文章不是 tailwind 的新手教學,而是記錄一些我認為在對這個套件有了基本了解後,可以搭配使用,進而讓開發更輕鬆的工具與訣竅。

搭配工具

官方 prettier 套件

連結:prettier-plugin-tailwindcss

目的:讓所有的 tailwind class 根據官方推薦的順序(base layer >> components layer >> utilities layer)排列,確保使用到的樣式都不會被權重(specificity)問題影響。另外,這個 plugin 預設也會幫忙移除多餘的空白(space)與重複出現的樣式。最後,統一樣式的排序也能讓閱讀程式碼的人比較輕鬆。

官方 plugin

@tailwindcss/typography

對文章常見元件提供預設樣式,比如標題的 margin 與清單的樣式,實際效果可參考官方範例。適合不想花太多時間自己調教文章樣式的人。

在極致懶惰的情況下,可以只在整篇文章的容器加上 class="prose" 就好。不過此 plugin 也提供客製化的選項,比如在不同螢幕寬(breakpoint)調整字體大小或是微調 .prose 之下各式元件的預設樣式


@tailwindcss/forms:對表單常見元件提供預設樣式,目前的支援列表可參考 README

需注意輸入元件要帶入 type 設定,比如 input[type='text']


@tailwindcss/container-queries:如名稱所示,安裝此 plugin 後就能使用 tailwind class 來實現 container query。

支援一次性使用的 query 尺寸,也支援透過 tailwind.config 來複寫全域尺寸設定。

cheat sheet

搜尋 tailwind cheat sheet 後,挑一個看起來順眼的使用即可。個人目前是使用 Flowbite 的 cheat sheet,因為有深色模式、點一下就能複製、支援搜尋結果的 expand/collapse。

目的:減少開發時額外的心智負荷,幫助開發者快速找到還沒背起來的樣式——所以絕大多數的注意力能用於解決核心問題,不會被「回想樣式如何設定」打斷思考流程。

操作

關於重複樣式

當大量重複的樣式出現在多個元件時,除了「直接擷取重複的樣式,包裝出(抽象化)一個帶有基本樣式的元件」以外,其實也可以考慮以下方式:

簡單來說,「重複」這件事情沒有那麼可怕,有時候問題其實有抽象化以外的解決方式。尤其抽象化會增加閱讀、理解程式碼的門檻,在執行前可以評估抽象化帶來的好處是否大於日後維護的成本。

關於 @apply

…don’t use @apply just to make things look “cleaner”.

不要「只」因為想讓樣式看起來比較簡潔而使用 @apply,比如以下不良示範:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn-primary {
    @apply py-2 px-5 bg-violet-500 text-white font-semibold rounded-full shadow-md hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75;
  }
}

理由是:這種使用 @apply 的方式,就和直接手寫 CSS 樣式沒什麼兩樣,失去很多使用 tailwind 系統的優點——你需要發想 CSS 樣式的名稱、需要在不同的檔案之間切換才能知道樣式的設定。日後修改一個 @apply 樣式時,你不確定是否會有預期外的影響。最後,打包(bundle)完的檔案尺寸也會比較大。

@apply 比較推薦的應用場合,是在需要將 tailwind 的樣式權杖(design token)套用在第三方套件的時候。

關於動態樣式

「不要」動態組合 tailwind 樣式,比如以下錯誤示範:

const meetCondition = Math.random() >= 0.5;
const dynamicClass = `text-${meetCondition ? 'green' : 'red'}-500`;

<h1 class={dynamicClass}>Hello World</h1>;

理由是:tailwind 會檢查整個專案,並只產生有使用到的樣式。而 tailwind 的檢查機制又是「完整比對 class 名稱」(出自官方文件)。所以 tailwind 無法辨認出上述動態組出的 text-green-500text-red-500

解決方式:需要動態樣式時,要完整列出 tailwind class 名稱:

const meetCondition = Math.random() >= 0.5;
const dynamicClass = meetCondition ? 'text-green-500' : 'text-red-500';

<h1 class={dynamicClass}>Hello World</h1>;

更多資訊請參考官方文件 的說明。

實用樣式

以下是從一些教學影片匯集出來,不需要開發者再從頭造輪子的實用內建樣式:

參考文件

本筆記大部分的工具與技巧出自以下三部 YouTube 影片,再搭配 tailwind 官方文件整理為筆記: