Tailwind 4 已經面世一段時間了,團隊於 2024 年 3 月首次開源了他們的進展。在我看來,最值得注意的變化之一是轉變從基於 JavaScript 的配置到基於 CSS 的配置。 Tailwind 4 目前處於測試階段,據我所知,團隊仍在應對一些挑戰,特別是 Safari 相容性。
注意:在本文後面,我們將假設您使用基於組件的框架/庫,但所討論的概念可以輕鬆轉移到其他方法。
我聽到了一些對此的抱怨,尤其是來自 TypeScript 用戶的抱怨。然而,Tailwind 4.0 的路線圖確實包括對經典 tailwind.config.js 的支援作為其首要任務:
支援 JavaScript 設定檔 - 重新引入與經典 tailwind.config.js 檔案的相容性,以便輕鬆遷移到 v4。
也就是說,這似乎主要是為了遷移目的,可能不是一個可持續的長期解決方案。
在底層,Tailwind 4 使用新的 @property CSS 規則來定義內部自訂屬性。
我們使用 @property 來定義具有適當類型和約束的內部自訂屬性
就目前情況而言,我無法在 VS 程式碼中找到對 @property 規則的語法高亮支持,我已經聯繫了 Bluesky,看看是否有人比我更幸運。
我希望更好的@property 支援將來能夠為我們提供幫助,稍後會詳細介紹。
@property 規則表示直接在樣式表中註冊自訂屬性,而無需執行任何 JavaScript。有效的 @property 規則會產生已註冊的自訂屬性,這類似於使用等效參數呼叫 registerProperty()。
現在我們已經介紹了 Tailwind 4 中即將發生的變化及其潛在影響,讓我們花點時間討論一下設計代幣。如果您不熟悉這個術語,這裡有一個快速解釋:設計令牌是一種以一致、可重複使用的格式(通常作為變數)儲存和管理設計決策的方法。它們以結構化的方式代表了設計系統的關鍵視覺屬性,例如顏色、排版、間距、陰影。目標是集中這些設計值,以便它們可以在不同的平台和工具之間輕鬆更新、維護和共享。
設計系統通常由兩種主要類型的值組成:系統值和組件值。例如,您的系統值可能如下所示:
const SYSTEM_TOKENS: ISystemTokens = { /* ... */ COLORS: { /* ... */ GREEN: { LIGHT: "#E0E5D9", MEDIUM: "#3F6212", DARK: "#28331A", } /* ... */ }, TYPOGRAPHY: { /* ... */ } /* ... */ }
然後,您可以在元件令牌中引用系統值,如下所示:
import { SYSTEM_TOKENS } from "..."; const BUTTON_VALUES: IButtonTokens = { /* ... */ COLORS: { /* ... */ BACKGROUND: SYSTEM_TOKENS.COLORS.GREEN.DARK, /* ... */ }, TYPOGRAPHY: { /* ... */ } /* ... */ }
如果您有興趣了解有關設計系統的更多信息,那麼值得探索像 Material Design 這樣的知名系統。
大約一週前,我寫了一篇文章,討論我一直使用的使用 Tailwind CSS 建立元件變體的替代方法。簡而言之,本文探討如何利用 CSS 變數和 Tailwind 來管理複雜的變體,透過動態元件屬性和變數來對應內嵌來設定變體值。如果您對我如何得出這種方法感到好奇,您可以在這裡閱讀更多相關內容:使用 Tailwind CSS 編寫元件變體的不同方法。
我們應該先辨識元件中依賴設計令牌的部分。如前所述,這將包括顏色、排版、間距以及設計中不可或缺的任何其他固定係統值。讓我們來看看以下沒有設計標記的 Button 組件:
<button> <p>In the example above, we can pinpoint several values that can be tokenized. Each of the following classes could correspond to a value in our design system:</p>
Now that we've identified the values that can be tokenised, we can categorise them into two groups: static values and dynamic values. Static values are those in your component that remain constant, while dynamic values are those that can change based on the props passed to the component. For our example we'll make the padding (p-4) static, while the text colour (text-white) and background (bg-red) should be set dynamically via a theme prop.
First we need to define our System tokens in the new Tailwind CSS config:
@import "tailwindcss"; @theme { --color-white: #FFFFFF; --color-green-light: #E0E5D9; --color-green-medium: #3F6212; --color-green-dark: #28331A; --color-red-light: #F4CCCC; --color-red-medium: #D50000; --color-red-dark: #640000; --spacing-sm: 1rem; --spacing-md: 2rem; }
接下來我們需要建立 system.tokens.ts 檔案:
export type TColor = "--color-white" | "--color-green-light" | "--color-green-medium" | "--color-green-dark" | "--color-red-light" | "--color-red-medium" | "--color-red-dark"; export type TSpacing = "--spacing-sm" | "--spacing-md"; interface ISystemTokens { COLORS: { WHITE: TColor; GREEN: { LIGHT: TColor; MEDIUM: TColor; DARK: TColor; }, RED: { LIGHT: TColor; MEDIUM: TColor; DARK: TColor; } }, SPACING: { SMALL: TSpacing; MEDIUM: TSpacing; } } export const SYSTEM_TOKENS: ISystemTokens { COLORS: { WHITE: "--color-white"; GREEN: { LIGHT: "--color-green-light"; MEDIUM: "--color-green-light"; DARK: "--color-green-light"; }, RED: { LIGHT: "--color-red-light"; MEDIUM: "--color-red-medium"; DARK: "--color-red-dark"; } }, SPACING: { SMALL: "--spacing-sm"; MEDIUM: "--spacing-md"; } }
系統設計令牌可以在設計中引用,如下所示:
$system.COLORS.GREEN.LIGHT.
在理想的世界中,我們可以直接將 CSS 檔案的 @property 規則中的類型匯出到 TColor 和 TSpacing 類型中,就像 SCSS 匯入如何轉換為 JavaScript 一樣。不幸的是,據我所知,目前這是不可能的。
現在我們已經實作了系統令牌,我們可以開始將它們整合到我們的元件中。第一步是設定我們的
回顧一下,我們的 Button 組件的結構如下:
<button> <p>Earlier, we discussed the distinction between static values (like p-4) and dynamic values (like bg-red and text-white). This distinction will guide how we organise our design tokens. Static properties, like p-4, should be grouped under STATIC, while dynamic properties, like bg-red and text-white, should be grouped under the appropriate prop identifier. In this case, since we’re controlling bg-red and text-white through a theme prop, they should be placed under the THEME section in our tokens file. For our example we'll assume 2 theme variables - PRIMARY and SECONDARY.<br> </p> <pre class="brush:php;toolbar:false">import { SYSTEM_TOKENS, TColor, TSpacing } from "./system.tokens.ts"; import { TTheme } from "./Button"; // PRIMARY, SECONDARY interface IButtonStaticTokens { padding: TSpacing; } interface IButtonThemeTokens { backgroundColor: TColor; textColor: TColor; } export const STATIC: IButtonStaticTokens { padding: "--spacing-sm"; } export const THEME: IButtonStaticTokens { PRIMARY: { backgroundColor: "--color-red-dark"; textColor: "--color-red-light"; }, SECONDARY: { backgroundColor: "--color-green-dark"; textColor: "--color-green-light"; }; }
元件設計標記可以在設計中引用,如下所示:$component.Button.THEME.PRIMARY.backgroundColor。我對命名約定的偏好是使用:
$component.
$component:區分 $system 和 $component 令牌
PROP_NAME:常數大小寫
PROP_VALUE:應遵循內部 prop 值大小寫
代幣名稱(背景顏色):駝峰式*
這最終是個人喜好問題,由您決定什麼最適合您的工作流程。
正如我在文章前面提到的,我之前寫過關於探索使用 Tailwind CSS 編寫組件變體的不同方法的文章。我將在這裡引用該方法,所以如果您還沒有閱讀過它,首先查看它可能會有所幫助,以了解該方法背後的上下文。
本文的這一部分將假設您正在使用 Javascript 框架或函式庫來建立元件。
我們需要將現有的 tokenisable 類別替換為由 css 變數支援的 Tailwind 類別。請注意,變數名稱與我們的 2 個 Button 元件令牌介面 IButtonStaticTokens 和 IButtonThemeTokens 中的變數名稱相符;
<p>現在我們已經更新了類,我們需要動態應用元件樣式並更新變數。為了實現這一點,我們將在元件上使用variableMap 函數。本質上,這個函數將我們的標記從 Button.tokens.ts 直接映射到元件上的內聯 CSS 變量,然後我們的類別可以引用這些變數。有關變數映射的範例,請參閱本文末尾。 <br> </p> <pre class="brush:php;toolbar:false">; <h2> 結論 </h2> <p>我期待 Tailwind 4 的發布以及團隊從現在到那時所做的改變。我喜歡嘗試各種想法來應對設計令牌、變體和類型安全方面的一些挑戰。 </p> <p>這是一種實驗性方法,我相信會有一些強烈的意見。 </p> <p>如果您覺得這篇文章有趣或有用,請在 Bluesky(我在這裡最活躍)、Medium、Dev 和/或 Twitter 上關注我。 </p>
以上是探索 Tailwind 4 中的 Typesafe 設計標記的詳細內容。更多資訊請關注PHP中文網其他相關文章!