tailwind.config.js 檔案的 content 區段是設定所有 HTML 範本、JavaScript 元件和任何其他包含 Tailwind 類別名稱的來源檔案的路徑。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  // ...
}

本指南涵蓋所有您需要知道的內容,以確保 Tailwind 為您的專案產生所有必要的 CSS。


設定來源路徑

Tailwind CSS 透過掃描所有 HTML、JavaScript 元件和任何其他範本檔案的類別名稱來運作,然後為這些樣式產生所有對應的 CSS。

為了讓 Tailwind 產生所有您需要的 CSS,它需要知道專案中包含任何 Tailwind 類別名稱的每個檔案。

在組態檔案的 content 區段中設定所有內容檔案的路徑

tailwind.config.js
/** @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 的內容,這可能不是你想要的

不要使用極其廣泛的模式

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './**/*.{html,js}',
  ],
  // ...
}

如果你有任何需要掃描的文件位於專案的根目錄(通常是 index.html 檔案),請獨立列出該檔案,以便其他模式可以更具體

具體說明你的內容模式

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './components/**/*.{html,js}',
    './pages/**/*.{html,js}',
    './index.html',
  ],
  // ...
}

有些框架將其主要的 HTML 進入點隱藏在與其他範本不同的位置(通常是 public/index.html),因此如果你要將 Tailwind 類別新增到該檔案,請確保它也包含在你的組態中

如果適用,請記得包含你的 HTML 進入點

tailwind.config.js
module.exports = {
  content: [
    './public/index.html',
    './src/**/*.{html,js}',
  ],
  // ...
}

如果你有任何用於操作 HTML 以新增類別的 JavaScript 檔案,請務必也包含這些檔案

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // ...
    './src/**/*.js',
  ],
  // ...
}
src/spaghetti.js
// ...
menuButton.addEventListener('click', function () {
  let classList = document.getElementById('nav').classList
  classList.toggle('hidden')
  classList.toggle('block')
})
// ...

同樣重要的是,不要掃描任何 CSS 檔案 — 將 Tailwind 組態為掃描你的 範本,其中使用你的類別名稱,而不是 Tailwind 正在產生的 CSS 檔案。

切勿在你的內容組態中包含 CSS 檔案

tailwind.config.js
/** @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 中用於切換選單

spaghetti.js
<script>
  menuButton.addEventListener('click', function () {
    let classList = document.getElementById('nav').classList
    classList.toggle('hidden')
    classList.toggle('block')
  })
</script>

透過使用這種非常簡單的方法,Tailwind 能夠與任何程式語言極為可靠地運作,例如 JSX

Button.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-600text-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 功能

main.css
@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 掃描這些元件以尋找類別名稱

tailwind.config.js
module.exports = {
  content: [
    './components/**/*.{html,js}',
    './pages/**/*.{html,js}',
    './node_modules/@my-company/tailwind-components/**/*.js',
  ],
  // ...
}

這將確保 Tailwind 也為這些元件產生所有必要的 CSS。

如果你在具有工作區的單一儲存庫中工作,你可能需要使用 require.resolve 來確保 Tailwind 可以看到你的內容檔案

tailwind.config.js
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

tailwind.config.js
module.exports = {
  content: {
    relative: true,
    files: [
      './pages/**/*.{html,js}',
      './components/**/*.{html,js}',
    ],
  },
  // ...
}

這很可能會成為下一個主要版本的框架預設行為。

設定原始內容

如果出於任何原因,您需要設定 Tailwind 掃描一些原始內容,而不是檔案內容,請使用具有 raw 鍵的物件,而不是路徑

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
    { raw: '<div class="font-bold">', extension: 'html' },
  ],
  // ...
}

這沒有很多有效的用例 — 安全列示 通常才是您真正想要的。


安全列示類別

為了獲得最小的檔案大小和最佳的開發體驗,我們強烈建議依賴您的 content 組態,盡可能告訴 Tailwind 要產生哪些類別。

安全列示是最後的手段,僅應在無法針對特定內容掃描類別名稱的情況下使用。這些情況很少見,你幾乎不需要這個功能。

如果你需要確保 Tailwind 產生內容檔案中不存在的特定類別名稱,請使用 safelist 選項

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    'bg-red-500',
    'text-3xl',
    'lg:text-4xl',
  ]
  // ...
}

這項功能可能於你的網站顯示使用者產生內容時派上用場,而你希望使用者能在內容中使用 Tailwind 類別的受限集合,這些類別可能不存在於你自己的網站原始檔案中。

使用正規表示式

Tailwind 支援基於樣式的安全列示,適用於你需要安全列示大量類別的情況

tailwind.config.js
/** @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 選項包含它們

tailwind.config.js
/** @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 忽略它在你的內容中偵測到的特定類別

tailwind.config.js
/** @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 選項,在提取類別之前轉換任何與特定檔案副檔名相符的內容

tailwind.config.js
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 用於偵測特定檔案副檔名的類別名稱的邏輯

tailwind.config.js
/** @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 元件。

tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{html,js}',
    './src/**/*.{html,js,jsx}'
  ],
  // ...
}

或是在專案進行中建立一個新的資料夾,但最初未包含在內,且忘記將其新增至您的組態。

tailwind.config.js
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 中的副檔名不符。

tailwind.config.js
/** @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 建置時不會變更的目錄

tailwind.config.js
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-allconcurrently 的套件來編譯你的 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",
  },
}

無論如何,請務必 查看現有的問題開啟一個新的問題,這樣我們才能找出問題並嘗試改善與你所使用的任何工具的相容性。