Tailwind CSS v3.1:你想瘋狂一下嗎?來吧,讓我們瘋狂一下!

Adam Wathan

自從我們發布 Tailwind CSS v3.0 以來,已經過了六個月左右,即使從那時起我們一直在程式碼庫中收集許多小改進,但我們仍然沒有那個獨特的功能,可以讓你說「好吧,是時候發布新版本了」

然後在幾週前的某個隨機的星期六晚上,我正在我們的 Discord 中與 Robin 討論如何使用 :has 以及文件中更深層的類別來鎖定 html 元素,並解釋說如果我們新增對任意變體的支援,我認為它會是什麼樣子——這是我一年多來一直想解決的問題

Adam Wathan: I think if we do arbitrary variants, the syntax should just be that exact thing, '[html:has(&)]:bg-blue-500'. Feel like that is pretty flexible, like anything you can do with a real variant you can also do with an arbitrary variant since they are the same thing. '[&>*:not(:first-child)]:pl-4'.
Robin: This is going to break my brain haha because '[html:has(&)]:bg-blue-500' would be used as a literal inside the '&'. That in combination with other variants... 🤯.
Adam Wathan: 😅 it'll be a brain melter for sure. The CSS would be this lol 'html:has([html:has(&)]:bg-blue-500 {"{"} background: blue 500 }'.
Robin: exactly haha. ok, now I want to try that brb.

二十分鐘後,Robin 有了一個可運作的概念驗證(在六行程式碼中!),在 Jordan 在我們的類別偵測引擎中執行了約一小時的正規表示式奇蹟之後,任意變體誕生了,我們有了一個值得發布的功能。

所以它來了 — Tailwind CSS v3.1!有關每個修復和改進的完整清單,請查看發行說明,但這裡是一些重點

從 npm 安裝最新版本的 tailwindcss 來升級你的專案

npm install tailwindcss@latest

或者啟動一個 Tailwind Play,直接在瀏覽器中玩所有的新好東西。


第一方 TypeScript 型別

我們現在為你在使用 Tailwind 時使用的所有 JS API 提供型別,最值得注意的是 tailwind.config.js 檔案。這表示你會獲得各種有用的 IDE 支援,並且更容易對你的組態進行變更,而無需經常參考文件。

要設定它,只需在你的組態定義上方新增類型註解

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

如果你是 TypeScript 的忠實粉絲,你可能會喜歡研究實際的類型定義——那裡有很多有趣的東西,可以支援如此潛在複雜的物件。

CLI 中內建的 CSS 導入支援

如果你使用我們的 CLI 工具來編譯你的 CSS,postcss-import 現在已直接內建,因此你可以將自訂 CSS 組織到多個檔案中,而無需任何額外設定。

@import "tailwindcss/base";@import "./select2-theme.css";@import "tailwindcss/components";@import "tailwindcss/utilities";

如果你沒有使用我們的 CLI 工具,而是使用 Tailwind 作為 PostCSS 外掛程式,你仍然需要像使用 autoprefixer 一樣自行安裝和設定 postcss-import,但如果你正在使用我們的 CLI 工具,這將完全正常運作。

如果你正在使用我們的獨立 CLI 並且完全不想安裝任何節點相依性,這特別方便。

在使用主題函式時變更顏色不透明度

我不認為很多人知道這一點,但 Tailwind 會向你的 CSS 檔案公開一個 theme() 函式,可讓您從組態檔案中抓取值 — 有點像將它們變成您可以重複使用的變數。

select2-theme.css
.select2-dropdown {  border-radius: theme(borderRadius.lg);  background-color: theme(colors.gray.100);  color: theme(colors.gray.900);}/* ... */

但一個限制是,你無法調整以這種方式抓取的任何顏色的 alpha 通道。因此,在 v3.1 中,我們新增了使用斜線語法來調整不透明度的支援,就像你可以使用現代 rgbhsl CSS 顏色函式一樣

select2-theme.css
.select2-dropdown {  border-radius: theme(borderRadius.lg);  background-color: theme(colors.gray.100 / 50%);  color: theme(colors.gray.900);}/* ... */

我們也讓它與你的 tailwind.config.js 檔案中的 theme 函式一起運作

tailwind.config.js
module.exports = {  content: [    // ...  ],  theme: {    extend: {      colors: ({ theme }) => ({        primary: theme("colors.blue.500"),        "primary-fade": theme("colors.blue.500 / 75%"),      }),    },  },  plugins: [],};

你甚至可以在任意值中使用這些東西,這非常瘋狂 — 說實話,對於奇怪的自訂漸層和其他東西來說非常有用

<div class="bg-[image:linear-gradient(to_right,theme(colors.red.500)_75%,theme(colors.red.500/25%))]">  <!-- ... --></div>

凡是能避免編輯 CSS 檔案的方法,我都支持,對吧?

更輕鬆的 CSS 變數顏色設定

如果你喜歡將顏色定義和設定為 CSS 變數,你現在的 tailwind.config.js 檔案中可能有一些可怕的樣板程式碼,如下所示

tailwind.config.js
function withOpacityValue(variable) {  return ({ opacityValue }) => {    if (opacityValue === undefined) {      return `rgb(var(${variable}))`;    }    return `rgb(var(${variable}) / ${opacityValue})`;  };}module.exports = {  theme: {    colors: {      primary: withOpacityValue("--color-primary"),      secondary: withOpacityValue("--color-secondary"),      // ...    },  },};

在 v3.1 中,我們新增了使用格式字串定義顏色的支援,而無需使用函式,使得情況不再那麼糟糕

tailwind.config.js
module.exports = {  theme: {    colors: {      primary: "rgb(var(--color-primary) / <alpha-value>)",      secondary: "rgb(var(--color-secondary) / <alpha-value>)",      // ...    },  },};

你可以直接撰寫一個具有 <alpha-value> 佔位符的字串,而不是撰寫一個接收 opacityValue 引數的函式,而 Tailwind 會根據公用程式將該佔位符取代為正確的 alpha 值。

如果你之前沒有看過任何這些內容,請查看我們更新的使用 CSS 變數文件以取得更多詳細資訊。

邊框間距公用程式

我們新增了用於 border-spacing 屬性的新公用程式集合,因此你可以控制在使用獨立邊框時表格邊框之間的空間

城市
印第安納州印第安納波利斯
俄亥俄州哥倫布
密西根州底特律
<table class="border-separate border-spacing-2 ...">  <thead>    <tr>      <th class="border border-slate-300 ...">State</th>      <th class="border border-slate-300 ...">City</th>    </tr>  </thead>  <tbody>    <tr>      <td class="border border-slate-300 ...">Indiana</td>      <td class="border border-slate-300 ...">Indianapolis</td>    </tr>    <!-- ... -->  </tbody></table>

我知道你在想什麼 — 「我這輩子從來沒有想過要建立一個看起來像那樣的表格...」 — 但聽我說一下!

當你建置一個具有黏性標頭列的表格,並且想要在標題下設定持久的底邊框時,這種情況實際上非常有用

捲動此表格以查看運作中的黏性標頭列

名稱角色
Courtney Henry管理員
Tom Cook成員
Whitney Francis管理員
Leonard Krasner擁有者
Floyd Miles成員
Emily Selman成員
Kristin Watson管理員
Emma Dorsey成員
Alicia Bell管理員
Jenny Wilson擁有者
Anna Roberts成員
Benjamin Russel成員
Jeffrey Webb管理員
Kathryn Murphy成員
<table class="border-separate border-spacing-0">  <thead class="bg-gray-50">    <tr>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Name</th>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Email</th>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Role</th>    </tr>  </thead>  <tbody class="bg-white">    <tr>      <td class="border-b border-gray-200 ...">Courtney Henry</td>      <td class="border-b border-gray-200 ...">courtney.henry@example.com</td>      <td class="border-b border-gray-200 ...">Admin</td>    </tr>    <!-- ... -->  </tbody></table>

你可能會認為這裡可以直接使用 border-collapse,因為你實際上不想要邊框之間有任何間距,但你就錯了。如果沒有 border-separateborder-spacing-0,邊框會滾動離開,而不是固定在標題下方。CSS 是不是很有趣?

請查看邊框間距的文件以了解更多詳細資訊。

啟用和選用的變體

我們為 :enabled:optional 偽類新增了新的變體,這些變體會在表單元素啟用和可選時鎖定它們。

「但是 Adam,我為什麼需要這些?啟用和可選甚至不是狀態,它們是預設值。你到底有沒有在做網站啊?」

哎喲,這很傷人,因為這是事實 — 我現在幾乎只是寫電子郵件,然後在 GitHub 上一遍又一遍地回答相同的問題。

但是請看這個停用按鈕的範例

<button type="button" class="bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 ..." disabled>Processing...</button>

請注意,當你將滑鼠游標移到按鈕上方時,即使它已停用,背景顏色仍然會改變?在此版本之前,你通常會像這樣修正它

<button  type="button"  class="bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 disabled:hover:bg-indigo-500 ..."  disabled>  Processing...</button>

但是有了新的 enabled 修飾符,你可以改成這樣寫

<button type="button" class="bg-indigo-500 hover:enabled:bg-indigo-400 disabled:opacity-75 ..." disabled>  Processing...</button>

當按鈕停用時,我們不是將滑鼠游標移上時的顏色覆寫回預設顏色,而是組合 hoverenabled 變體,這樣就可以直接在按鈕停用時不套用滑鼠移上時的樣式。我認為這樣更好!

這裡有一個範例,將新的 optional 修飾符與我們的同層級狀態功能結合使用,以隱藏非必填欄位的小「必填」提示

必填
必填
<form>  <div>    <label for="email" ...>Email</label>    <div>      <input required class="peer ..." id="email" />      <div class="peer-optional:hidden ...">Required</div>    </div>  </div>  <div>    <label for="name" ...>Name</label>    <div>      <input class="peer ..." id="name" />      <div class="peer-optional:hidden ...">Required</div>    </div>  </div>  <!-- ... --></form>

這讓你可以在所有表單群組中使用相同的標記,並讓 CSS 處理所有條件式呈現,而不是自己處理。還不錯吧!

偏好對比變體

你知道有一個 prefers-contrast 媒體查詢嗎?嗯,它現在有了,而且 Tailwind 也直接支援了。

當使用者請求更多或更少的對比度時,通常透過作業系統的協助工具偏好設定(例如 macOS 上的「增加對比度」)使用新的 contrast-morecontrast-less 變體來修改你的設計。

嘗試在開發人員工具中模擬 `prefers-contrast: more` 以查看變更

我們需要這個來竊取你的身分。

<form>  <label class="block">    <span class="block text-sm font-medium text-slate-700">Social Security Number</span>    <input      class="border-slate-200 placeholder-slate-400 contrast-more:border-slate-400 contrast-more:placeholder-slate-500"    />    <p class="mt-2 text-sm text-slate-600 opacity-10 contrast-more:opacity-100">We need this to steal your identity.</p>  </label></form>

我為此寫了一些文件,但老實說,我這裡寫的比那裡還多。

設定原生對話背景樣式

有一個相當新的HTML <dialog> 元素,具有令人驚訝的良好瀏覽器支援,如果你喜歡走在時代尖端,它值得你玩玩看。

對話方塊有一個新的 ::backdrop 偽元素,會在對話方塊開啟時呈現,而 Tailwind CSS v3.1 新增了一個新的 backdrop 修飾符,你可以使用它來設定這個元素的樣式

<dialog class="backdrop:bg-slate-900/50 ...">  <form method="dialog">    <!-- ... -->    <button value="cancel">Cancel</button>    <button>Submit</button>  </form></dialog>

如果你想更深入研究這個東西,我建議你閱讀MDN 對話方塊文件 — 這很令人興奮,但有很多東西需要了解。

適用於變體的任意值

好,這個對我來說才是真正的重點 — 你知道我們提供你addVariant API 來建立你自己的自訂變體嗎?

tailwind.config.js
const plugin = require("tailwindcss/plugin");module.exports = {  // ...  plugins: [    plugin(function ({ addVariant }) {      addVariant("third", "&:nth-child(3)");    }),  ],};

...而且你知道我們有任意值,可以直接在 HTML 中使用你想要的任何值嗎?

] --><div class="top-[117px]">  <!-- ... --></div>

嗯,Tailwind CSS v3.1 引入了任意變體,讓你直接在 HTML 中建立你自己的臨時變體

<div class="[&:nth-child(3)]:py-0">  <!-- ... --></div>

對於那些感覺需要參數化的變體來說,這非常有用,例如在使用 @supports 查詢時,如果瀏覽器支援特定的 CSS 功能,則新增樣式

<div  class="bg-white [@supports(backdrop-filter:blur(0))]:bg-white/50 [@supports(backdrop-filter:blur(0))]:backdrop-blur">  <!-- ... --></div>

你甚至可以使用此功能來鎖定具有任意變體的子元素,例如 [&>*]

  • Kristen Ramos

    kristen.ramos@example.com

  • Floyd Miles

    floyd.miles@example.com

  • Courtney Henry

    courtney.henry@example.com

<ul role="list" class="space-y-4 [&>*]:rounded-lg [&>*]:bg-white [&>*]:p-4 [&>*]:shadow">  <li class="flex">    <img class="h-10 w-10 rounded-full" src="..." alt="" />    <div class="ml-3 overflow-hidden">      <p class="text-sm font-medium text-slate-900">Kristen Ramos</p>      <p class="truncate text-sm text-slate-500">kristen.ramos@example.com</p>    </div>  </li>  <!-- ... --></ul>

你甚至可以設定第二個子 lidiv 內的第一個 p 的樣式,但僅限於 hover

嘗試將滑鼠游標移到文字「Floyd Miles」上方

  • Kristen Ramos

    kristen.ramos@example.com

  • Floyd Miles

    floyd.miles@example.com

  • Courtney Henry

    courtney.henry@example.com

<ul  role="list"  class="space-y-4 [&>*]:rounded-lg [&>*]:bg-white [&>*]:p-4 [&>*]:shadow hover:[&>li:nth-child(2)>div>p:first-child]:text-indigo-500">  <!-- ... -->  <li class="flex">    <img class="h-10 w-10 rounded-full" src="..." alt="" />    <div class="ml-3 overflow-hidden">      <p class="text-sm font-medium text-slate-900">Floyd Miles</p>      <p class="truncate text-sm text-slate-500">floyd.miles@example.com</p>    </div>  </li>  <!-- ... --></ul>

現在,你應該這樣做嗎?可能不常這樣做,但老實說,當你嘗試設定無法直接變更的 HTML 樣式時,這會是一個非常有用的跳脫方式。它是一把鋒利的刀,但最好的廚師不是用安全剪刀準備食物的。

試用一下它們,我敢打賭你會發現當情況需要時,它們是一個很棒的工具。我們正在我們正在開發的這些新網站範本的幾個棘手的地方使用它們,而且體驗比建立自訂類別好得多。


這就是 Tailwind CSS v3.1!這只是一個小版本變更,所以沒有重大變更,你應該可以透過安裝最新版本來更新你的專案

npm install tailwindcss@latest

如需完整的變更清單,包括錯誤修正和我這裡沒有提到的幾個小改進,請深入研究 GitHub 上的版本說明

我已經有很多關於 Tailwind CSS v3.2 的想法(甚至可能終於有文字陰影了?!),但現在我們正努力將這些新的網站範本推向終點線。請期待在接下來的一兩週內看到關於該主題的另一次更新!

直接在你的收件匣中收到我們所有的更新資訊。
註冊我們的電子報。