核心概念
管理重複並建立可重複使用的抽象化。
Tailwind 鼓勵採用 以實用程式為先 的工作流程,其中設計僅使用低階實用程式類別來實作。這是避免過早抽象化及其所帶來的痛點的有效方法。
但當然隨著專案的成長,您不可避免地會發現重複使用常見的實用程式組合,以便在許多不同的地方重新建立相同的設計。
例如,在以下範本中,您可以看到每個頭像圖片的實用程式類別重複了五次
<div>
<div class="flex items-center space-x-2 text-base">
<h4 class="font-semibold text-slate-900">Contributors</h4>
<span class="rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700">204</span>
</div>
<div class="mt-3 flex -space-x-2 overflow-hidden">
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
</div>
<div class="mt-3 text-sm font-medium">
<a href="#" class="text-blue-500">+ 198 others</a>
</div>
</div>
別擔心!在本指南中,您將瞭解在專案中重複使用樣式的不同策略,以及何時採用每種策略的最佳實務。
很多時候,這樣的重複甚至不是真正的問題,因為它們全部集中在一個地方,或者甚至根本不存在,因為您正在迭代項目陣列,並且只編寫一次標記。
如果您需要重複使用的樣式只需要在單一檔案中重複使用,多游標編輯和迴圈就是管理任何重複項目的最簡單方法。
當重複出現在單一檔案中的元素群組時,最簡單的處理方式是使用 多游標編輯,快速選取並同時編輯每個元素的類別清單
<nav class="flex justify-center space-x-4">
<a href="/dashboard" class="font-medium px-3 py-2 text-slate-700 rounded-lg hover:bg-slate-100 hover:text-slate-900">Home</a>
<a href="/team" class="font-medium px-3 py-2 text-slate-700 rounded-lg hover:bg-slate-100 hover:text-slate-900">Team</a>
<a href="/projects" class="font-medium px-3 py-2 text-slate-700 rounded-lg hover:bg-slate-100 hover:text-slate-900">Projects</a>
<a href="/reports" class="font-medium px-3 py-2 text-slate-700 rounded-lg hover:bg-slate-100 hover:text-slate-900">Reports</a>
</nav>
你會驚訝於這項功能有多常成為最佳解決方案。如果你能快速同時編輯所有重複的類別清單,就不需要引入任何額外的抽象。
在你假設需要萃取元件或為某個東西建立自訂類別之前,請確定你實際上在範本中使用它超過一次。
很多時候,在已渲染頁面中出現超過一次的設計元素,實際上只撰寫一次,因為實際標記是在迴圈中渲染的。
例如,本指南開頭的重複頭像在實際專案中幾乎一定會在迴圈中呈現
<div>
<div class="flex items-center space-x-2 text-base">
<h4 class="font-semibold text-slate-900">Contributors</h4>
<span class="rounded-full bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700">204</span>
</div>
<div class="mt-3 flex -space-x-2 overflow-hidden">
{#each contributors as user}
<img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="{user.avatarUrl}" alt="{user.handle}"/>
{/each}
</div>
<div class="mt-3 text-sm font-medium">
<a href="#" class="text-blue-500">+ 198 others</a>
</div>
</div>
如果您願意,您甚至可以使用迴圈或 map
改寫導覽範例
<nav className="flex sm:justify-center space-x-4">
{[
['Home', '/dashboard'],
['Team', '/team'],
['Projects', '/projects'],
['Reports', '/reports'],
].map(([title, url]) => (
<a href={url} className="rounded-lg px-3 py-2 text-slate-700 font-medium hover:bg-slate-100 hover:text-slate-900">{title}</a>
))}
</nav>
當元素像這樣在迴圈中呈現時,實際的類別清單只會寫一次,因此沒有實際的重複問題需要解決。
如果您需要在多個檔案中重複使用一些樣式,最佳策略是建立一個 元件(如果您使用 React、Svelte 或 Vue 等前端架構),或一個 範本部分(如果您使用 Blade、ERB、Twig 或 Nunjucks 等範本語言)。
<template>
<div>
<img class="rounded" :src="img" :alt="imgAlt">
<div class="mt-2">
<div>
<div class="text-xs text-slate-600 uppercase font-bold tracking-wider">{{ eyebrow }}</div>
<div class="font-bold text-slate-700 leading-snug">
<a :href="url" class="hover:underline">{{ title }}</a>
</div>
<div class="mt-2 text-sm text-slate-600">{{ pricing }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['img', 'imgAlt', 'eyebrow', 'title', 'pricing', 'url']
}
</script>
現在,您可以在任意多個地方使用此元件,同時仍為樣式保留單一真實來源,因此可以輕易地在同一個地方一起更新它們。
除非元件是單一 HTML 元素,否則定義元件所需資訊無法單獨在 CSS 中擷取。對於任何稍微複雜的事物,HTML 結構與 CSS 同樣重要。
不要依賴 CSS 類別來擷取複雜元件
您有新訊息!
<!-- Even with custom CSS, you still need to duplicate this HTML structure -->
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>
<style>
.chat-notification { /* ... */ }
.chat-notification-logo-wrapper { /* ... */ }
.chat-notification-logo { /* ... */ }
.chat-notification-content { /* ... */ }
.chat-notification-title { /* ... */ }
.chat-notification-message { /* ... */ }
</style>
即使您為元件中的不同元素建立類別,例如:每次要使用此元件時,您仍然必須複製 HTML。當然,您可以在單一位置更新每個實例的字型大小,但是如果您需要將標題轉換為連結時該怎麼辦?
元件和範本部分比僅限 CSS 的抽象化能更好地解決此問題,因為元件可以封裝 HTML 和樣式。變更每個實例的字型大小與使用 CSS 一樣容易,但現在您也可以在單一位置將所有標題轉換為連結。
建立範本部分或 JavaScript 元件
您有新訊息!
function Notification({ imageUrl, imageAlt, title, message }) {
return (
<div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
<div className="shrink-0">
<img className="h-12 w-12" src={imageUrl.src} alt={imageAlt}>
</div>
<div>
<div className="text-xl font-medium text-black">{title}</div>
<p className="text-slate-500">{message}</p>
</div>
</div>
)
}
當您建立此類元件和範本部分時,沒有理由使用任何其他內容,除了實用程式類別,因為您已經有樣式的單一真實來源。
如果您使用傳統的範本語言,例如 ERB 或 Twig,為像按鈕這樣小的東西建立範本部分,可能會覺得大材小用,不如使用簡單的 CSS 類別,例如 btn
。
雖然強烈建議您為更複雜的元件建立適當的範本部分,但當範本部分感覺過於繁瑣時,您可以使用 Tailwind 的 @apply
指令,將重複的實用模式萃取到自訂 CSS 類別中。
以下是如何使用 @apply
來組合現有實用工具,讓 btn-primary
類別看起來像什麼
<!-- Before extracting a custom class -->
<button class="py-2 px-5 bg-violet-500 text-white font-semibold rounded-full shadow-md hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75">
Save changes
</button>
<!-- After extracting a custom class -->
<button class="btn-primary">
Save changes
</button>
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-primary {
@apply py-2 px-5 bg-violet-500 text-white font-semibold rounded-full shadow-md hover:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-400 focus:ring-opacity-75;
}
}
在 函式和指令 文件中深入了解 @apply
和 @layer
。
無論您做什麼,請不要使用 @apply
,只為了讓事情看起來「更乾淨」。是的,佈滿 Tailwind 類別的 HTML 範本有點醜陋。在擁有大量自訂 CSS 的專案中進行變更更糟。
如果您開始對所有事情都使用 @apply
,基本上您只是在重新撰寫 CSS,並放棄 Tailwind 提供的所有工作流程和可維護性優勢,例如
如果您要使用 @apply
,請將它用於非常小、高度可重複使用的項目,例如按鈕和表單控制項 — 即使如此,也只有在您沒有使用 React 等架構時,這時元件會是更好的選擇。