Tailwind CSS Just-in-Time Mode

2022-07-27 15:27 更新

Just-in-Time Mode

適用于 Tailwind CSS v2.1+ 的更快、更強大的按需引擎。


此功能目前處于預覽階段。語義版本控制未涵蓋預覽功能,并且隨著我們不斷完善它們,某些細節(jié)可能會發(fā)生變化。

Tailwind CSS v2.1 為 Tailwind CSS 引入了新的即時編譯器,可在您創(chuàng)作模板時按需生成樣式,而不是在初始構建時提前生成所有內(nèi)容。

這有很多優(yōu)點:

  • 閃電般的快速構建時間。使用我們的 CLI 最初編譯 Tailwind 可能需要 3-8 秒,而在 webpack 項目中則需要 30-45 秒,因為 webpack 難以處理大型 CSS 文件。無論您使用什么構建工具,這個庫甚至可以在大約 800 毫秒內(nèi)編譯最大的項目(增量重建速度最快 3 毫秒)。
  • 每個變體都是開箱即用的。由于文件大小的考慮,默認情況下通常不會啟用 ?focus-visible?, ?active?, ?disabled ?等變體。由于此庫按需生成樣式,因此您可以隨時使用所需的任何變體。你甚至可以像 ?sm:hover:active:disabled:opacity-75? 一樣堆疊它們。永遠不要再次配置您的變體。
  • 無需編寫自定義 CSS 即可生成任意樣式。曾經(jīng)需要一些不屬于您的設計系統(tǒng)的超特定值,例如 ?top: -113px? 用于古怪的背景圖像?由于樣式是按需生成的,因此您可以根據(jù)需要使用方括號表示法(如 ?top-[-113px]?)為此生成實用程序。也適用于變體,例如 ?md:top-[-113px]?。
  • 您的 CSS 在開發(fā)和生產(chǎn)中是相同的。由于樣式是根據(jù)需要生成的,因此您無需清除未使用的樣式以進行生產(chǎn),這意味著您可以在所有環(huán)境中看到完全相同的 CSS。再也不用擔心意外清除生產(chǎn)中的重要樣式。
  • 開發(fā)中更好的瀏覽器性能。由于開發(fā)版本與生產(chǎn)版本一樣小,因此瀏覽器不必解析和管理數(shù)兆字節(jié)的預生成 CSS。在具有大量擴展配置的項目中,這使開發(fā)工具的響應速度更快。

啟用 JIT 模式

要啟用即時模式,請在 ?tailwind.config.js ?文件中將 ?mode ?選項設置為 ?'jit'?:

  // tailwind.config.js
  module.exports = {
   mode: 'jit',
    purge: [
      // ...
    ],
    theme: {
      // ...
    }
    // ...
  }

由于 JIT 模式通過掃描模板文件按需生成 CSS,因此在 ?tailwind.config.js? 文件中使用所有模板路徑配置 ?purge ?選項至關重要,否則您的 CSS 將為空:

  // tailwind.config.js
  module.exports = {
    mode: 'jit',
   // These paths are just examples, customize them to match your project structure
   purge: [
     './public/**/*.html',
     './src/**/*.{js,jsx,ts,tsx,vue}',
   ],
    theme: {
      // ...
    }
    // ...
  }

現(xiàn)在,當您啟動開發(fā)服務器或構建運行器時,Tailwind 將按需生成您的樣式,而不是預先生成所有內(nèi)容。

新的功能

所有變體均已啟用

由于樣式是按需生成的,因此無需配置每個核心插件可用的變體。

<input class="disabled:opacity-75">

您可以將 ?focus-visible?, ?active?, ?disabled?, ?even ?等變體與任何實用程序結合使用,而無需對 tailwind.config.js 文件進行任何更改。

可堆疊變體

所有變體都可以組合在一起,以輕松針對非常特定的情況,而無需編寫自定義 CSS。

<button class="md:dark:disabled:focus:hover:bg-gray-400">

任意值支持

許多實用程序使用新的方括號表示法支持任意值,以表明您正在“breaking out”您的設計系統(tǒng)。

<!-- Sizes and positioning -->
<img class="absolute w-[762px] h-[918px] top-[-325px] right-[62px] md:top-[-400px] md:right-[80px]" src="/crazy-background-image.png">

<!-- Colors -->
<button class="bg-[#1da1f1]">Share on Twitter</button>

<!-- Complex grids -->
<div class="grid-cols-[1fr,700px,2fr]">
  <!-- ... -->
</div>

這對于構建像素完美的設計非常有用,其中有一些元素需要超特定的樣式,例如營銷網(wǎng)站上精心定位的背景圖像。

動態(tài)值

請注意,在使用任意值時,您仍然需要編寫可清除的 HTML,并且您的類需要作為完整的字符串存在,以便 Tailwind 正確檢測它們。

不要使用字符串連接來創(chuàng)建類名

<div className={`mt-[${size === 'lg' ? '22px' : '17px' }]`}></div>

動態(tài)選擇一個完整的類名

<div className={ size === 'lg' ? 'mt-[22px]' : 'mt-[17px]' }></div>

Tailwind 不包括任何類型的客戶端運行時,因此類名需要在構建時可靜態(tài)提取,并且不能依賴于客戶端上更改的任何類型的任意動態(tài)值。在這些情況下使用內(nèi)聯(lián)樣式,或者將 Tailwind 與 Emotion 等 CSS-in-JS 庫結合起來,如果它對您的項目有意義的話。

不能從動態(tài)值計算任意值

<div class="bg-[{{ userThemeColor }}]"></div>

對真正的動態(tài)或用戶定義的值使用內(nèi)聯(lián)樣式

<div style="background-color: {{ userThemeColor }}"></div>

帶空格的值

同樣重要的是要注意 CSS 類不能包含空格,這意味著您不能按原樣使用 ?calc(100px - 4rem)? 或 ?1fr 700px 2fr? 之類的任意值。要在您的類名中使用這樣的任意值,您需要刪除 ?calc ?調(diào)用內(nèi)容中的空格,并用 ?1fr 700px 2fr? 等列表中的逗號替換空格。 Tailwind 會在 ?calc ?調(diào)用中自動為您重新引入空格,并在生成相應的 CSS 時將列表中的逗號替換為空格。

不要在任意值中使用空格

<div class="h-[calc(1000px - 4rem)]">...</div>
<div class="grid-cols-[1fr 700px 2fr]">...</div>

酌情刪除空格或用逗號替換

<div class="h-[calc(1000px-4rem)]">...</div>
<div class="grid-cols-[1fr,700px,2fr]">...</div>

模棱兩可的值

如果您將 CSS 變量用作任意值,它有時會導致類名對引擎來說不明確,例如:

<!-- Is this a font size utility, or a text color utility? -->
<div class="text-[var(--mystery-var)]">

在這些情況下,您可以通過在任意值前面加上類型名稱來向引擎提供提示:

<div class="text-[color:var(--mystery-var)]">

支持的類型有:

  • ?length ?
  • ?color ?
  • ?angle ?
  • ?list?

內(nèi)置重要修飾符

你可以通過在開頭添加一個 ?!? 字符來使任何實用程序變得重要。

<p class="font-bold !font-medium">
  This will be medium even though bold comes later in the CSS.
</p>

?!? 總是出現(xiàn)在實用程序名稱的開頭,在任何變體之后,但在任何前綴之前。

<div class="sm:hover:!tw-font-bold">

這在您需要提高特異性的極少數(shù)情況下很有用,因為您與一些您無法控制的樣式交戰(zhàn)。原文:(This can be useful in rare situations where you need to increase specificity because you’re at war with some styles you don’t control.)

顏色不透明度速記

無需使用 ?bg-opacity-50?、?text-opacity-25? 或 ?placeholder-opacity-40? 等實用程序,JIT 引擎讓您只需將不透明度添加到顏色的末尾:

 <div class="bg-red-500 bg-opacity-25">
 <div class="bg-red-500/25">

這意味著您現(xiàn)在可以在 Tailwind 中的任何位置更改顏色的不透明度,即使我們以前沒有特定的不透明度實用程序,例如在漸變中:

<div class="bg-gradient-to-r from-red-500/50">

不透明度值取自您的 ?opacity ?比例,但您也可以使用方括號表示法使用任意不透明度值:

<div class="bg-red-500/[0.31]">

每邊邊框顏色

自 2017 年以來就提出請求,但由于文件大小的考慮而被遺漏,JIT 引擎最終增加了對獨立設置元素每一側的邊框顏色的支持:

<div class="border-2 border-t-blue-500 border-r-pink-500 border-b-green-500 border-l-yellow-500">
  <!-- ... -->
</div>

偽元素變體

JIT 引擎添加了對樣式偽元素的支持,例如 ?::before?、?::after?、?::first-letter?、?::first-line?、?::marker? 和 ?::selection?。

<div class="before:block before:bg-blue-500 after:flex after:bg-pink-300">

當您在變體之前或之后添加任何內(nèi)容時,?content ?屬性會自動設置為 ?""? 以確保元素實際上是可見的。要更改內(nèi)容屬性,請使用新的內(nèi)容實用程序。

如前所述,我們還添加了對其他偽元素的支持,例如 ?::selection?,它允許您設置選定文本的樣式:

<p class="selection:bg-yellow-300 ...">
  I'm yellow when you highlight me.
</p>

或者 ?::marker? 偽元素,它允許您設置列表標記的樣式:

<ul class="marker:text-gray-500">
  <li>Odio et sed.</li>
  <li>Voluptatem perferendis optio est id.</li>
  <li>Accusamus et aut odit.</li>
</ul>

內(nèi)容實用程序

我們添加了新的 ?content-*? 實用程序來設置 ?content ?屬性——與新的 ?before ?和 ?after ?變體一起非常有用:

<div class="before:content-['hello'] before:block ...">

它們甚至支持 ?attr ?函數(shù)之類的東西,因此您可以引用存儲在屬性中的值:

<div data-content="hello world" class="before:content-[attr(data-content)] before:block ...">

詳盡的偽類支持

除了 ?hover?, ?focus ?等現(xiàn)有內(nèi)容之外,我們還添加了對我們認為有意義的每個偽類的支持,例如 ?required?, ?invalid?, ?placeholder-shown? 等等。

<input class="invalid:border-red-500 ...">

以下是新偽類變體的完整列表:

  • ?only? (for ?only-child?)
  • ?first-of-type?
  • ?last-of-type?
  • ?only-of-type?
  • ?target?
  • ?default?
  • ?indeterminate?
  • ?placeholder-shown?
  • ?autofill?
  • ?required?
  • ?valid?
  • ?invalid?
  • ?in-range?
  • ?out-of-range?

插入符號顏色實用程序(Caret color utilities)

您現(xiàn)在可以使用新的 ?caret-{color}? 實用程序在表單字段中設置光標的顏色:

<input class="caret-red-500">

這些可以使用 ?tailwind.config.js? 文件的 ?theme ?部分中的 ?caretColor ?鍵進行自定義。

兄弟選擇器變體(Sibling selector variants)

與我們多年來支持的基于父狀態(tài)設置元素樣式的 ?group-*? 變體類似,您可以使用新的 ?peer-*? 變體根據(jù)其先前兄弟元素之一的狀態(tài)設置元素樣式:

<label>
  <input type="checkbox" class="peer sr-only">
  <span class="h-4 w-4 bg-gray-200 peer-checked:bg-blue-500">
    <!-- ... -->
  </span>
  <!-- ... -->
</label>

只需使用 ?peer ?類標記您感興趣的前一個同級,然后使用 ?peer-hover?、?peer-checked?、?peer-focus? 等變體來根據(jù)該同級的狀態(tài)設置元素的樣式。

簡化的變換、濾鏡和背景濾鏡組合(Simplified transform, filter, and backdrop-filter composition)

不再需要 ?transform?, ?filter ?和 ?backdrop-filter? 類來“enable”它們各自的可組合實用程序集。

 <div class="transform scale-50 filter grayscale backdrop-filter backdrop-blur-sm">
 <div class="scale-50 grayscale backdrop-blur-sm">

現(xiàn)在,只要您使用任何相關的子實用程序,這些功能就會自動啟用。

改變

我們將 JIT 引擎視為我們計劃作為 Tailwind CSS v3.0 發(fā)布的內(nèi)容的預覽,因此在選擇加入時需要考慮一些小的重大更改。我們真的不希望這些會影響很多人,但值得一讀,尤其是當您注意到項目外觀的任何細微差異時。

變體被一起渲染(Variants are rendered together)

在經(jīng)典引擎中,實用程序變體在每個實用程序生成的 CSS 中組合在一起,如下所示:

/* Classic engine */

.bg-black { background-color: #000 }
.hover\:bg-black:hover { background-color: #000 }
.focus\:bg-black:focus { background-color: #000 }

/* ... */

.opacity-75 { opacity: 0.75 }
.hover\:opacity-75:hover { opacity: 0.75 }
.focus\:opacity-75:focus { opacity: 0.75 }

/* ... */

.translate-x-4 { --tw-translate-x: 1rem }
.hover\:translate-x-4:hover { --tw-translate-x: 1rem }
.focus\:translate-x-4:focus { --tw-translate-x: 1rem }

在 JIT 引擎中,變體按變體分組在一起:(In the JIT engine, variants are grouped together per variant:)

/* JIT engine */

.bg-black { background-color: #000 }
.opacity-75 { opacity: 0.75 }
.translate-x-4 { --tw-translate-x: 1rem }

/* ... */

.hover\:bg-black:hover { background-color: #000 }
.hover\:opacity-75:hover { opacity: 0.75 }
.hover\:translate-x-4:hover { --tw-translate-x: 1rem }

/* ... */

.focus\:bg-black:focus { background-color: #000 }
.focus\:opacity-75:focus { opacity: 0.75 }
.focus\:translate-x-4:focus { --tw-translate-x: 1rem }

這意味著不能再為每個核心插件指定變體順序——所有實用程序的變體將始終處于相同的順序。如果您以前需要 ?hover ?來取消 ?focus ?以獲取特定實用程序并確保 ?hover ?在變體列表中位于 ?focus ?之后,這對您來說可能是個問題。

 // tailwind.config.js
  module.exports {
    // Variant configuration (including order) is not respected by the JIT engine
   variants: {
     // ...
     backgroundColor: ['focus', 'hover']
   }
  }

要使用 JIT 引擎處理這些情況,我們建議使用堆疊變體:(To handle these situations with the JIT engine, we recommend using stacked variants instead:)

<!-- This ensures the element is blue on hover, even if it's also focused -->
<div class="focus:bg-red-500 hover:bg-blue-500 hover:focus:bg-blue-500">

堆疊變體允許您指定當多個變體同時處于活動狀態(tài)時應如何設置樣式,因此您無需嘗試使用 ?hover ?樣式覆蓋 ?focus ?樣式,而是顯式聲明當 ?hover ?和 ?focus ?同時處于活動狀態(tài)時元素的外觀。

變體在@tailwind 變體中插入(Variants are inserted at @tailwind variants)

在經(jīng)典引擎中,所有實用程序變體都作為 ?@tailwind utilities? 指令的一部分注入。

在 JIT 引擎中,變體在 ?@tailwind variants? 指令中注入,該指令已從 ?@tailwind screens? 重命名。

該指令是可選的(就像 ?@tailwind screens? 一樣),并且僅在您想要顯式控制實用程序變體的注入位置時才有用。默認情況下,它們總是在樣式表的最后注入。

如果您之前使用過 ?@tailwind screens?,則應更新代碼以使用 ?@tailwind variants?:

 @tailwind base;
  @tailwind components;
  @tailwind utilities;
 @tailwind screens;
 @tailwind variants;

  /* Some custom CSS... */

?@tailwind variants? 功能被認為是一個高級避風港,我們建議默認省略它。只有當你的項目在沒有它的情況下無法正常工作時,你才應該使用它,而這只有在你將 Tailwind 引入到一個傳統(tǒng)的系統(tǒng)時才是真的,這個系統(tǒng)有一個非常脆弱的現(xiàn)有CSS代碼庫,它的樣式絕對需要在樣式表的最末端才能工作。

不需要顯式啟用轉(zhuǎn)換和過濾器

使用 JIT 引擎時,不需要 ?transform?, ?filter ?和 ?backdrop-filter? 類來 "enabling" 這些功能:

 <div class="transform scale-50 filter grayscale backdrop-filter backdrop-blur-sm">
 <div class="scale-50 grayscale backdrop-blur-sm">

這意味著您不能再期望 transforms 和 filters 默認處于休眠狀態(tài),并通過添加 ?transform?, ?filter ?或 ?backdrop-filter? 有條件地激活。

(This means you can no longer expect transforms and filters to be dormant by default, and conditionally activated by adding transform, filter, or backdrop-filter.)

相反,您需要將任何變體放在子實用程序本身上:

 <div class="scale-105 -translate-y-1 hover:transform">
 <div class="hover:scale-105 hover:-translate-y-1">

限制

這個新引擎幾乎支持經(jīng)典引擎中存在的所有功能,再加上大量的新功能,如果所有的東西都要預先生成,那是不可能的。

然而,由于引擎工作方式的性質(zhì),有一些事情目前是不可能的。

  • ?safelist? 選項不支持正則表達式。因為默認情況下沒有生成CSS,所以 safelist 必須是一個完整的類名的列表。不可能用正則表達式來做安全列表,因為沒有一個預先生成的類名列表可以與該正則表達式相匹配。
  • 當配置為函數(shù)時,prefix 選項無法檢測完整的類名。因為我們不預先生成類名,所以我們只能將實用程序“namespace”傳遞給自定義前綴函數(shù)。有關示例,請參見此評論
  • 您只能 ?@apply? 屬于核心的類、由插件生成或在 ?@layer? 規(guī)則中定義的類。您目前不能 ?@apply? 未在 ?@layer? 規(guī)則中定義的任意 CSS 類,盡管我們將來可能會添加對此的支持。(You can only @apply classes that are part of core, generated by plugins, or defined within a @layer rule. You can’t currently @apply arbitrary CSS classes that aren’t defined within a @layer rule, although we may add support for this in the future.)

我們還在解決與某些構建工具的一些兼容性問題,您可以在我們的 issue tracker 中關注這些問題。

如果您遇到任何其他問題或發(fā)現(xiàn)任何錯誤,請打開一個 issue,以便我們修復它。

故障排除

刪除類時不會刪除樣式

當 JIT 引擎在監(jiān)視模式下運行時,您可能會注意到,當您向 HTML 添加一個類然后刪除它時,該類仍然存在于您的 CSS 中。

這不是一個錯誤,而是一種刻意的性能優(yōu)化,它極大地提高了增量重建的速度,尤其是在大型項目中。

我們建議您在部署到生產(chǎn)之前始終在單獨的一次性構建中編譯您的 CSS,以便您可以縮小輸出。對于大多數(shù)現(xiàn)代工具(例如 Next.js),這種事情會自動發(fā)生,因為您編譯的 CSS 永遠不會提交給版本控制。

如果您希望 Tailwind 在監(jiān)視模式下從頭開始完全重建 CSS,保存 ?tailwind.config.js? 文件或 CSS 輸入文件將使所有緩存無效并觸發(fā)新的重建。

保存內(nèi)容文件時樣式不更新

從 Tailwind CSS v2.2+ 開始,JIT 引擎依賴 PostCSS 的目錄依賴消息(directory dependency messages)將您的內(nèi)容文件注冊為使用構建工具的 CSS 構建依賴項。這些是 PostCSS 的一個相當新的補充(于 2021 年 5 月添加),并非所有構建工具都已更新以支持它們。

如果您更改內(nèi)容文件時 CSS 沒有重新構建,請嘗試將 ?TAILWIND_MODE=watch? 設置為您的監(jiān)視腳本的一部分,以告訴 Tailwind 改用舊的依賴項跟蹤策略,該策略適用于許多構建工具。

例如,如果您使用 ?postcss-cli?,請在您的 dev/watch 腳本中設置 ?TAILWIND_MODE=watch?:

// package.json
{
  // ...
  scripts: {
    // Set TAILWIND_MODE=watch when starting your dev server
    "dev": "TAILWIND_MODE=watch postcss -i tailwind.css -o build.css --watch",

    // Do not set TAILWIND_MODE for one-off builds
    "build": "postcss -i tailwind.css -o build.css --minify",
    // ...
  },
  // ...
}

如果你使用的是Windows,我們推薦使用 cross-env 來設置腳本中的環(huán)境變量。

請注意,設置 ?TAILWIND_MODE=watch? 將在后臺啟動一個長時間運行的監(jiān)視進程,因此如果您在嘗試進行一次性構建時設置了該環(huán)境變量,它看起來就像構建掛起。

僅當您實際運行開發(fā)服務器/監(jiān)視進程時,并且僅當您的構建工具尚不支持 PostCSS 目錄依賴消息時,才應設置 ?TAILWIND_MODE=watch?。此標志是不兼容工具的臨時解決方法,最終將在 Tailwind CSS 的未來版本中刪除。

樣式在無限循環(huán)中重建(Styles rebuild in an infinite loop)

如果你的 CSS 似乎在無限循環(huán)中重建,很有可能是因為你的構建工具在注冊依賴項(registering dependencies)時不支持 PostCSS 的 ? glob ?選項。

許多構建工具(例如 webpack)不支持此選項,因此我們只能告訴它們查看特定文件或整個目錄。例如,我們不能告訴 webpack 只查看目錄中的 ?*.html? 文件。

這意味著如果構建 CSS 導致這些目錄中的任何文件發(fā)生更改,則會觸發(fā)重建,即使更改的文件與 glob 中的擴展名不匹配。

// tailwind.config.js
module.exports = {
  purge: [
    // Your CSS will rebuild any time *any* file in `src` changes
    './src/**/*.{html,js}',
  ],
  // ...
}

因此,如果你在觀察? src/**/*.html? 的變化,但你卻把你的CSS輸出文件寫到 ?src/css/styles.css?,你會在一些工具中得到一個無限的重建循環(huán)。

理想情況下,我們可以在控制臺中警告您這一點,但許多工具都非常支持它(包括我們自己的 CLI 工具),而且我們沒有可靠的方法來檢測您正在使用的構建工具。

您有幾個選項可以解決此問題:

  1. 在 ?purge ?配置中使用更具體的路徑。確保只包含在 CSS 構建時不會更改的目錄。
  2.   // tailwind.config.js
      module.exports = {
        purge: [
         './src/**/*.{html,js}',
         './src/pages/**/*.{html,js}',
         './src/components/**/*.{html,js}',
         './src/layouts/**/*.{html,js}',
         './src/index.html',
        ],
        // ...
      }

    如有必要,請調(diào)整您的實際項目目錄結構,以確保您可以定位您的模板文件,而不會意外捕獲您的 CSS 文件或其他構建工件(如清單文件)。

  3. 使用支持 PostCSS glob 的構建工具。如果您絕對無法更改清除配置或目錄結構,最好的辦法是使用具有完整 glob 支持的工具單獨編譯 CSS。我們建議使用 Tailwind CLI,它是一種快速、簡單、專門構建的工具,用于使用 Tailwind 編譯 CSS。

它似乎無法正常工作

如果您遇到奇怪的、難以描述的輸出問題,或者看起來根本無法正常工作,很有可能是因為您的構建工具不正確(或根本不支持)PostCSS 依賴消息。目前一個已知的例子是 Stencil

當您遇到此類問題時,我們建議您使用 Tailwind CLI 工具單獨編譯您的 CSS,而不是嘗試將 Tailwind 集成到您現(xiàn)有的工具中。

你可以使用 ?npm-run-all? 或 ?concurrently ?這樣的包,通過在你的項目中添加一些腳本,在你通常的開發(fā)命令旁邊編譯你的CSS,就像這樣。

// package.json
{
  // ...
  "scripts": {
    "dev": "npm-run-all --parallel dev:*",
    "dev:parcel": "parcel serve ./src/index.html",
    "dev:css": "tailwindcss -o src/tailwind.css --watch",
    "build": "npm-run-all build:css build:parcel",
    "build:parcel": "parcel build ./src/index.html",
    "build:css": "tailwindcss -o src/tailwind.css --minify",
  },
}

無論哪種方式,請務必檢查現(xiàn)有問題打開一個新問題,以便我們找出問題并嘗試提高與您使用的任何工具的兼容性。

目前存在已知兼容性問題的工具包括:


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號