自訂
設定專案的內容來源。
tailwind.config.js
檔案的 content
區段是設定所有 HTML 範本、JavaScript 元件和任何其他包含 Tailwind 類別名稱的來源檔案的路徑。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
// ...
}
本指南涵蓋所有您需要知道的內容,以確保 Tailwind 為您的專案產生所有必要的 CSS。
Tailwind CSS 透過掃描所有 HTML、JavaScript 元件和任何其他範本檔案的類別名稱來運作,然後為這些樣式產生所有對應的 CSS。
為了讓 Tailwind 產生所有您需要的 CSS,它需要知道專案中包含任何 Tailwind 類別名稱的每個檔案。
在組態檔案的 content
區段中設定所有內容檔案的路徑
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}'
],
// ...
}
路徑設定為 glob 模式,讓您輕鬆比對專案中的所有內容檔案,而無需大量設定
*
比對除了斜線和隱藏檔案以外的所有內容**
比對零個或多個目錄{}
中使用逗號分隔值來比對選項清單Tailwind 使用 fast-glob 函式庫,請查看其文件以取得其他支援的模式功能。
路徑相對於您的專案根目錄,而非 您的 tailwind.config.js
檔案,因此如果您的 tailwind.config.js
檔案位於自訂位置,您仍應相對於專案根目錄撰寫路徑。
為了獲得最佳效能並避免誤判,請在您的內容設定中盡可能具體。
如果你使用像這樣一個非常廣泛的模式,Tailwind 甚至會掃描 node_modules
的內容,這可能不是你想要的
不要使用極其廣泛的模式
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./**/*.{html,js}',
],
// ...
}
如果你有任何需要掃描的文件位於專案的根目錄(通常是 index.html
檔案),請獨立列出該檔案,以便其他模式可以更具體
具體說明你的內容模式
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./components/**/*.{html,js}',
'./pages/**/*.{html,js}',
'./index.html',
],
// ...
}
有些框架將其主要的 HTML 進入點隱藏在與其他範本不同的位置(通常是 public/index.html
),因此如果你要將 Tailwind 類別新增到該檔案,請確保它也包含在你的組態中
如果適用,請記得包含你的 HTML 進入點
module.exports = {
content: [
'./public/index.html',
'./src/**/*.{html,js}',
],
// ...
}
如果你有任何用於操作 HTML 以新增類別的 JavaScript 檔案,請務必也包含這些檔案
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
// ...
'./src/**/*.js',
],
// ...
}
// ...
menuButton.addEventListener('click', function () {
let classList = document.getElementById('nav').classList
classList.toggle('hidden')
classList.toggle('block')
})
// ...
同樣重要的是,不要掃描任何 CSS 檔案 — 將 Tailwind 組態為掃描你的 範本,其中使用你的類別名稱,而不是 Tailwind 正在產生的 CSS 檔案。
切勿在你的內容組態中包含 CSS 檔案
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/**/*.css',
],
// ...
}
Tailwind 掃描你的原始碼以尋找類別的方式故意非常簡單 — 我們實際上不會解析或執行你用撰寫語言編寫的任何程式碼,我們只使用正規表示式來提取每個可能成為類別名稱的字串。
例如,這裡有一些 HTML,每個潛在的類別名稱字串都個別標示出來
<div class="md:flex">
<div class="md:flex-shrink-0">
<img class="rounded-lg md:w-56" src="/img/shopping.jpg" alt="Woman paying for a purchase">
</div>
<div class="mt-4 md:mt-0 md:ml-6">
<div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">
Marketing
</div>
<a href="/get-started" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">
Finding customers for your new business
</a>
<p class="mt-2 text-gray-600">
Getting a new business off the ground is a lot of hard work.
Here are five ideas you can use to find your first customers.
</p>
</div>
</div>
我們不會只將搜尋限制在 class="..."
屬性,因為你可以在任何地方使用類別,例如在某些 JavaScript 中用於切換選單
<script>
menuButton.addEventListener('click', function () {
let classList = document.getElementById('nav').classList
classList.toggle('hidden')
classList.toggle('block')
})
</script>
透過使用這種非常簡單的方法,Tailwind 能夠與任何程式語言極為可靠地運作,例如 JSX
const sizes = {
md: 'px-4 py-2 rounded-md text-base',
lg: 'px-5 py-3 rounded-lg text-lg',
}
const colors = {
indigo: 'bg-indigo-500 hover:bg-indigo-600 text-white',
cyan: 'bg-cyan-600 hover:bg-cyan-700 text-white',
}
export default function Button({ color, size, children }) {
let colorClasses = colors[color]
let sizeClasses = sizes[size]
return (
<button type="button" className={`font-bold ${sizeClasses} ${colorClasses}`}>
{children}
</button>
)
}
Tailwind 提取類別名稱的最重要含義是,它只會在原始檔中找到以完整不中斷字串存在的類別。
如果你使用字串內插或串接部分類別名稱,Tailwind 將找不到它們,因此不會產生對應的 CSS
不要動態建構類別名稱
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
在上面的範例中,字串 text-red-600
和 text-green-600
不存在,因此 Tailwind 不會產生這些類別。
相反地,請確保你使用的任何類別名稱都完整存在
始終使用完整的類別名稱
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
如果你使用 React 或 Vue 等元件庫,這表示你不應該使用 props 來動態建構類別
不要使用 props 來動態建構類別名稱
function Button({ color, children }) {
return (
<button className={`bg-${color}-600 hover:bg-${color}-500 ...`}>
{children}
</button>
)
}
相反地,將 props 映射到在建置時可以靜態偵測到的完整類別名稱
始終將 props 映射到靜態類別名稱
function Button({ color, children }) {
const colorVariants = {
blue: 'bg-blue-600 hover:bg-blue-500',
red: 'bg-red-600 hover:bg-red-500',
}
return (
<button className={`${colorVariants[color]} ...`}>
{children}
</button>
)
}
這具有額外的優點,例如讓你能夠將不同的 prop 值映射到不同的顏色色調
function Button({ color, children }) {
const colorVariants = {
blue: 'bg-blue-600 hover:bg-blue-500 text-white',
red: 'bg-red-500 hover:bg-red-400 text-white',
yellow: 'bg-yellow-300 hover:bg-yellow-400 text-black',
}
return (
<button className={`${colorVariants[color]} ...`}>
{children}
</button>
)
}
只要你在程式碼中始終使用完整的類別名稱,Tailwind 每次都能完美地產生所有 CSS。
如果你正在使用任何第三方函式庫(例如 Select2),並使用你自己的自訂 CSS 為該函式庫設定樣式,我們建議撰寫這些樣式時不要使用 Tailwind 的 @layer
功能
@tailwind base;
@tailwind components;
.select2-dropdown {
@apply rounded-b-lg shadow-md;
}
.select2-search {
@apply border border-gray-300 rounded;
}
.select2-results__group {
@apply text-lg font-bold text-gray-900;
}
/* ... */
@tailwind utilities;
這將確保 Tailwind 始終在你的 CSS 中包含這些樣式,這比設定 Tailwind 掃描第三方函式庫的原始程式碼容易得多。
如果你建立了自己的可重複使用元件組,並使用 Tailwind 設定其樣式,且在多個專案中匯入這些元件,請務必設定 Tailwind 掃描這些元件以尋找類別名稱
module.exports = {
content: [
'./components/**/*.{html,js}',
'./pages/**/*.{html,js}',
'./node_modules/@my-company/tailwind-components/**/*.js',
],
// ...
}
這將確保 Tailwind 也為這些元件產生所有必要的 CSS。
如果你在具有工作區的單一儲存庫中工作,你可能需要使用 require.resolve
來確保 Tailwind 可以看到你的內容檔案
const path = require('path');
module.exports = {
content: [
'./components/**/*.{html,js}',
'./pages/**/*.{html,js}',
path.join(path.dirname(require.resolve('@my-company/tailwind-components')), '**/*.js'),
],
// ...
}
預設情況下,Tailwind 會根據目前的工作目錄,而非 tailwind.config.js
檔案,解析非絕對內容路徑。如果你從不同的目錄執行 Tailwind,這可能會導致意外的結果。
若要始終解析相對於 tailwind.config.js
檔案的路徑,請使用物件符號表示法設定 content
組態,並將 relative
屬性設定為 true
module.exports = {
content: {
relative: true,
files: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
},
// ...
}
這很可能會成為下一個主要版本的框架預設行為。
如果出於任何原因,您需要設定 Tailwind 掃描一些原始內容,而不是檔案內容,請使用具有 raw
鍵的物件,而不是路徑
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
{ raw: '<div class="font-bold">', extension: 'html' },
],
// ...
}
這沒有很多有效的用例 — 安全列示 通常才是您真正想要的。
為了獲得最小的檔案大小和最佳的開發體驗,我們強烈建議依賴您的 content
組態,盡可能告訴 Tailwind 要產生哪些類別。
安全列示是最後的手段,僅應在無法針對特定內容掃描類別名稱的情況下使用。這些情況很少見,你幾乎不需要這個功能。
如果你需要確保 Tailwind 產生內容檔案中不存在的特定類別名稱,請使用 safelist
選項
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
safelist: [
'bg-red-500',
'text-3xl',
'lg:text-4xl',
]
// ...
}
這項功能可能於你的網站顯示使用者產生內容時派上用場,而你希望使用者能在內容中使用 Tailwind 類別的受限集合,這些類別可能不存在於你自己的網站原始檔案中。
Tailwind 支援基於樣式的安全列示,適用於你需要安全列示大量類別的情況
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
safelist: [
'text-2xl',
'text-3xl',
{
pattern: /bg-(red|green|blue)-(100|200|300)/,
},
],
// ...
}
樣式只能與基本實用程式名稱相符,例如 /bg-red-.+/
,如果樣式包含變體修改器,例如 /hover:bg-red-.+/
,則不會相符。
如果你想強制 Tailwind 為任何相符類別產生變體,請使用 variants
選項包含它們
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
safelist: [
'text-2xl',
'text-3xl',
{
pattern: /bg-(red|green|blue)-(100|200|300)/,
variants: ['lg', 'hover', 'focus', 'lg:hover'],
},
],
// ...
}
由於 Tailwind 使用非常簡單的方法來偵測內容中的類別名稱,你可能會發現產生了一些你實際上不需要的類別。
例如,這段 HTML 仍然會產生 container
類別,即使該類別實際上並未被使用
<div class="text-lg leading-8 text-gray-600">
Every custom pool we design starts as a used shipping container, and is
retrofitted with state of the art technology and finishes to turn it into
a beautiful and functional way to entertain your guests all summer long.
</div>
你可能還希望在這些類別與某些現有 CSS 衝突時,阻止 Tailwind 產生某些類別,但你不想對所有 Tailwind 類別加上前綴。
在這些情況下,你可以使用 blocklist
選項告訴 Tailwind 忽略它在你的內容中偵測到的特定類別
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
],
blocklist: [
'container',
'collapse',
],
// ...
}
blocklist
選項只會影響 Tailwind 會產生的 CSS,而不是你自己撰寫或從其他程式庫匯入的客製化 CSS。
與 safelist
不同,blocklist
選項只支援字串,而且你無法使用正規表示式來封鎖類別。
如果你正在以編譯為 HTML 的格式(例如 Markdown)撰寫內容,通常在掃描類別名稱之前,將該內容編譯為 HTML 是有意義的。
使用 content.transform
選項,在提取類別之前轉換任何與特定檔案副檔名相符的內容
const remark = require('remark')
module.exports = {
content: {
files: ['./src/**/*.{html,md}'],
transform: {
md: (content) => {
return remark().process(content)
}
}
},
// ...
}
使用 content.transform
時,您需要使用 content.files
提供來源路徑,而不是作為 content
下的頂層陣列。
使用 extract
選項來覆寫 Tailwind 用於偵測特定檔案副檔名的類別名稱的邏輯
/** @type {import('tailwindcss').Config} */
module.exports = {
content: {
files: ['./src/**/*.{html,wtf}'],
extract: {
wtf: (content) => {
return content.match(/[^<>"'`\s]*/g)
}
}
},
// ...
}
這是一個進階功能,大多數使用者不需要它 — Tailwind 中的預設萃取邏輯幾乎適用於所有專案。
與轉換一樣,在使用 content.extract
時,您需要使用 content.files
提供來源路徑,而不是作為 content
下的頂層陣列。
如果 Tailwind 未產生類別,請確認您的 content
組態正確,且符合所有正確的原始檔案。
常見的錯誤是遺漏檔案副檔名,例如您使用 jsx
而不是 js
作為 React 元件。
module.exports = {
content: [
'./src/**/*.{html,js}',
'./src/**/*.{html,js,jsx}'
],
// ...
}
或是在專案進行中建立一個新的資料夾,但最初未包含在內,且忘記將其新增至您的組態。
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}',
'./util/**/*.{html,js}'
],
// ...
}
也可能是您嘗試使用動態類別名稱,這無法運作,因為 Tailwind 實際上並未評估您的原始程式碼,且只能偵測靜態且未中斷的類別字串。
不要動態建構類別名稱
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
請務必在您的程式碼中始終使用完整的類別名稱。
始終使用完整的類別名稱
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
閱讀我們的文件,了解 動態類別名稱 的更多詳細資訊。
如果您的 CSS 似乎在無限迴圈中重建,很可能是因為您的建置工具不支援 glob
選項,當 註冊 PostCSS 相依性 時。
許多建置工具(例如 webpack)不支援此選項,因此我們只能告訴它們觀察特定檔案或整個目錄。例如,我們無法告訴 webpack 僅觀察目錄中的 *.html
檔案。
這表示如果建置您的 CSS 導致這些目錄中的任何檔案變更,則會觸發重建,即使變更的檔案與您的 glob 中的副檔名不符。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
// With some build tools, your CSS will rebuild
// any time *any* file in `src` changes.
'./src/**/*.{html,js}',
],
// ...
}
因此,如果您正在監控 src/**/*.html
的變更,但將 CSS 輸出檔案寫入 src/css/styles.css
,您將使用一些工具取得無限重建迴圈。
理想情況下,我們可以在主控台中對此發出警告,但許多工具完全支援它(包括我們自己的 CLI 工具),而且我們沒有可靠的方法來偵測您正在使用哪個建置工具。
若要解決此問題,請在您的 content
設定中使用更明確的路徑,並確保只包含在 CSS 建置時不會變更的目錄
module.exports = {
content: [
'./src/**/*.{html,js}',
'./src/pages/**/*.{html,js}',
'./src/components/**/*.{html,js}',
'./src/layouts/**/*.{html,js}',
'./src/index.html',
],
// ...
}
如有必要,請調整實際專案目錄結構,以確保您可以鎖定範本檔案,而不會意外擷取 CSS 檔案或其他建置產生的檔案,例如清單檔案。
如果您絕對無法變更內容設定或目錄結構,您的最佳選擇是使用支援完整 glob 的工具,來個別編譯 CSS。我們建議使用 Tailwind CLI,這是一個快速、簡單、專為使用 Tailwind 編譯 CSS 而建置的工具。
如果您遇到難以描述的輸出問題,或事情看起來根本無法運作,很有可能是因為您的建置工具不支援 PostCSS 相依性訊息(或根本不支援)。目前已知的一個範例是 Stencil。
當您遇到此類問題時,我們建議使用 Tailwind CLI 來個別編譯您的 CSS,而不是嘗試將 Tailwind 整合到您現有的工具中。
你可以使用像 npm-run-all
或 concurrently
的套件來編譯你的 CSS 與你平常的開發指令,透過在你的專案中加入一些腳本,如下所示
// package.json
{
// ...
"scripts": {
"start": "concurrently \"npm run start:css\" \"react-scripts start\"",
"start:css": "tailwindcss -o src/tailwind.css --watch",
"build": "npm run build:css && react-scripts build",
"build:css": "NODE_ENV=production tailwindcss -o src/tailwind.css -m",
},
}