善用 data-attributes 為 Tailwind CSS 設定動態樣式

更新於 發佈於 閱讀時間約 8 分鐘

Tailwind CSS 為什麼受歡迎

Tailwind CSS 是熱門的CSS框架,最大的賣點在於「原子化」,也就是「一個class 對應到一個css 樣式」。使用 Tailwind CSS 後,開發者再也不用花時間思考class的名稱,只要在元件中的 markup 寫好構成樣式所需的 class 名稱,Tailwind 就會在 build 的時候生成對應的css樣式,像這樣:

<p className="text-3xl font-bold text-blue-500">Hello World</p>;

搭配 Webpack 或 Vite 等打包工具,執行 build 命令後, Tailwind 就會幫我們在 build 之後的靜態檔案裡新增樣式:

.text-blue-500 {
--tw-text-opacity: 1;
color: rgb(59 130 246 / var(--tw-text-opacity));
}
Tailwind CSS 會根據 class 名稱,生成對應樣式。

Tailwind CSS 會根據 class 名稱,生成對應樣式。

此外,Tailwind CSS 在生成樣式時,有寫出的class才會生成對應的 CSS,因此不用擔心有像 BootStrap 等框架在網頁打包時,套件的css會讓檔案變得臃腫的情況。Tailwind 的好處還有避免同名的class之間樣式衝突等等,但這非本文重點,故不贅述。筆者希望把重點放在 Tailwind 難以解決的問題,和其解決方案上。


不易設定動態樣式

Tailwind 在 build 時生成樣式,因此要因應 client-side 的 state 或 prop 變化動態產生樣式會比較麻煩。面對這個問題,其中一種做法是使用如 clsx 的第三方套件,透過 JavaScript 在 runtime 時根據元件的狀態將 class 名稱組合成對應的樣式。


clsx 套件

clsx 是一個專門處理 CSS class 名稱的套件,他可以將物件、陣列甚至條件判斷轉換成字串,並計算出最終的 class 名稱。搭配 Tailwind 使用,可以讓動態樣式設定的開發者體驗更好:

const buttonClass = clsx("py-2 px-4 font-semibold rounded-lg text-white", {
"bg-blue-500": status === "Primary",
"bg-green-500": status === "Success",
"bg-red-500": status === "Danger",
});

return (
<div>
<button className={buttonClass}>{status}</button>
</div>
);

雖然 clsx 和 Tailwind 搭配已經十分好用,即使套件本身非常輕量化,畢竟仍會在打包時產生一些 JavaScript。那麼,有沒有不用第三方套件產生動態樣式的解決方案呢?


用data-* attribute 動態生成樣式

所幸 Tailwind CSS 在 3.2 版推出用 data-* attributes 動態生成樣式的方法。以下舉 React component 為例,說明如何透過 data 屬性的綁定,生成動態的 Tailwind classes:

import { useState, useEffect, useRef } from "react";

import Checkbox from "./Checkbox";

export default function App() {
const [status, setStatus] = useState("Primary");

const intervalRef = useRef(null);
useEffect(() => {
function switchBtnBackground(color) {
switch (color) {
case "Primary": {
return "Success";
}
case "Success": {
return "Danger";
}
case "Danger": {
return "Primary";
}
}
}

intervalRef.current = setInterval(() => {
setStatus((t) => switchBtnBackground(t));
}, 1500);

return () => clearInterval(intervalRef.current);
}, []);

return (
<div className="text-2xl border w-64">
<button
data-status={status}
className="w-full data-[status=Primary]:bg-[#007bff] text-white data-[status=Success]:bg-[#28a745] data-[status=Danger]:bg-[#dc3545] px-4 py-2 border-gray-500 rounded-sm text-center"
>
{btnText}
</button>
</div>
);
}


data attribute 是 HTML 內建的元素屬性,可以自定義元素的屬性,將網頁的狀態綁定在元素上。如上面的例子中,筆者將元件的狀態 status 綁定在按鈕上,當元件的狀態改變時,data-status 就會跟著改變。而 Tailwind 讓 data attribute 成為一種狀態,就像 media query 的 md/xl 等一樣,後面可以加上隨著data attribute值變化所套用的class 名稱,進而達到動態產生樣式的目的。

按鈕根據元件狀態變化,會有不同背景顏色。

按鈕根據元件狀態變化,會有不同背景顏色。



總結

data-attribute 讓使用Tailwind CSS 制定動態樣式變得更容易,且不需要依賴第三方套件,看起來十分美好。但 Tailwind 官方有提到:data attribute 只接受 arbitrary values,也就是開發者自定義的值,這也就代表會在 build 的時候額外生成classes。因此,如果元件內有大量的互動,造成樣式多變,使用 data attribute 也許不一定能減少打包檔案的大小。筆者認為,像clsx這樣處理多變樣式的套件,仍有其優勢,而data-* 屬性則適合在元件的動態較不複雜時使用。

arbitrary value 會在build 時生成額外的class,因此過度使用會讓css打包檔案變得很肥。

arbitrary value 會在build 時生成額外的class,因此過度使用會讓css打包檔案變得很肥。



參考資料

CLEANER Tailwind classes

Tailwind CSS v3.2: Dynamic breakpoints, multi-config, and container queries, oh my!

https://tailwindcss.com/blog/tailwindcss-v3-2#data-attribute-variants


留言
avatar-img
留言分享你的想法!
林博濂-avatar-img
2024/03/25
感謝分享!看完介紹會覺得能用clsx就盡量用,data-attribute 的原生寫法完全不吸引人XD
avatar-img
廖偉帆的沙龍
3會員
5內容數
我是Sail,這裡主要分享一些自己覺得有趣的前端議題。
廖偉帆的沙龍的其他內容
2024/05/30
在進行Electron 專案時,後端夥伴選擇將 sqlite 資料庫跟專案檔打包成一個執行檔。在開發過程中,前端的操作經常會更動到 db的資料,此時 Git 就會追蹤到 db 的變化,因此前端在推送檔案到遠端 repo 前,會需要將其移出 Git 追蹤範圍,該怎麼做?
Thumbnail
2024/05/30
在進行Electron 專案時,後端夥伴選擇將 sqlite 資料庫跟專案檔打包成一個執行檔。在開發過程中,前端的操作經常會更動到 db的資料,此時 Git 就會追蹤到 db 的變化,因此前端在推送檔案到遠端 repo 前,會需要將其移出 Git 追蹤範圍,該怎麼做?
Thumbnail
2024/05/13
在串接第三方 API時,需要定期刷新 token,那有沒有辦法針對 request 和 response 做配置,在 token 過期時先做刷新、再做請求呢?本文要介紹利用 axios 套件提供的攔截器刷新 token 的作法。
Thumbnail
2024/05/13
在串接第三方 API時,需要定期刷新 token,那有沒有辦法針對 request 和 response 做配置,在 token 過期時先做刷新、再做請求呢?本文要介紹利用 axios 套件提供的攔截器刷新 token 的作法。
Thumbnail
2024/05/01
在 Vue 專案中使用 Apollo Graphql Client 從 API 獲取資料,由於資料結構較為複雜,筆者便跟著網路教學使用 codegen 工具自動化產生 TypeScript 型別定義。在某個元件中,需要使用 defineProps 來撰寫型別定義,結果⋯⋯
Thumbnail
2024/05/01
在 Vue 專案中使用 Apollo Graphql Client 從 API 獲取資料,由於資料結構較為複雜,筆者便跟著網路教學使用 codegen 工具自動化產生 TypeScript 型別定義。在某個元件中,需要使用 defineProps 來撰寫型別定義,結果⋯⋯
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
在本章中,我們探討了CSS Grid佈局的基本概念和應用。CSS Grid提供了一個強大而靈活的二維佈局系統,使得處理複雜的網頁佈局變得更加簡單和直觀。我們學習了如何設置Grid容器和Grid項目,以及如何使用各種Grid屬性來定義和管理佈局。
Thumbnail
在本章中,我們探討了CSS Grid佈局的基本概念和應用。CSS Grid提供了一個強大而靈活的二維佈局系統,使得處理複雜的網頁佈局變得更加簡單和直觀。我們學習了如何設置Grid容器和Grid項目,以及如何使用各種Grid屬性來定義和管理佈局。
Thumbnail
這節課的學習目標是了解 CSS 的基本語法結構和使用方法。
Thumbnail
這節課的學習目標是了解 CSS 的基本語法結構和使用方法。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
使用靜態檔案下載 Bootstrap 的原因主要有以下幾點: 客製化:當你下載了 Bootstrap 的靜態檔案,你可以根據自己的需求來修改這些檔案。例如,你可以改變預設的顏色、字型大小、間距等,使其更符合你的網站風格。這是直接使用 CDN 所無法做到的。 效能優化:如果你的網站只使用 Boot
Thumbnail
使用靜態檔案下載 Bootstrap 的原因主要有以下幾點: 客製化:當你下載了 Bootstrap 的靜態檔案,你可以根據自己的需求來修改這些檔案。例如,你可以改變預設的顏色、字型大小、間距等,使其更符合你的網站風格。這是直接使用 CDN 所無法做到的。 效能優化:如果你的網站只使用 Boot
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
CSS 的繼承性是開發網頁樣式時的一個重要概念,它使得樣式設計更加靈活和高效,有助於提高程式碼的可讀性、一致性和可重用性,並加快開發速度,從而提供更好的開發體驗。
Thumbnail
CSS 的繼承性是開發網頁樣式時的一個重要概念,它使得樣式設計更加靈活和高效,有助於提高程式碼的可讀性、一致性和可重用性,並加快開發速度,從而提供更好的開發體驗。
Thumbnail
什麼是 CSS 預處理器 CSS 預處理器是一種工具,使用專門的語法來生成 CSS 樣式表。市面上有許多 CSS 預處理器可供選擇,它們通常會提供一些純 CSS 中沒有的功能,例如變數、混入、巢狀選擇器等。這些功能可以使 CSS 結構更易讀、更易於維護,並提高開發效率。 為什麼使用 CSS 預處
Thumbnail
什麼是 CSS 預處理器 CSS 預處理器是一種工具,使用專門的語法來生成 CSS 樣式表。市面上有許多 CSS 預處理器可供選擇,它們通常會提供一些純 CSS 中沒有的功能,例如變數、混入、巢狀選擇器等。這些功能可以使 CSS 結構更易讀、更易於維護,並提高開發效率。 為什麼使用 CSS 預處
Thumbnail
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
Thumbnail
data-* attributes 是 HTML 內建的屬性,可將網頁的狀態與元素進行綁定。而Tailwind CSS 在 3.2 版更新中推出使用 data-* attributes 自訂樣式的功能,讓樣式設定可以更動態多變。
Thumbnail
您對前端有興趣,對CSS不陌生。CSS新特性前應瞭解基本內容。CSS屬性制定經歷過程,瀏覽器私有前綴及處理,開發者對新特性漸進增強,優雅降級處理,Web標準定義、作用等。
Thumbnail
您對前端有興趣,對CSS不陌生。CSS新特性前應瞭解基本內容。CSS屬性制定經歷過程,瀏覽器私有前綴及處理,開發者對新特性漸進增強,優雅降級處理,Web標準定義、作用等。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News