善用 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
3會員
5內容數
我是Sail,這裡主要分享一些自己覺得有趣的前端議題。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
你可能也想看
Google News 追蹤
Thumbnail
在這一章中,我們介紹了 CSS 的過渡效果和動畫效果。過渡效果使 CSS 屬性的變化更加平滑,而動畫效果則允許我們更精細地控制元素的多個屬性隨時間變化的過程。我們通過基本語法和示例展示了如何使用這些效果,並提供了一個綜合應用的實踐案例來幫助理解。這些技術可以讓你的網頁更具互動性和動態效果。
Thumbnail
這節課的學習目標是了解 CSS 的基本語法結構和使用方法。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
在當今日新月異的數位時代,網站已經不僅僅是一個給人們提供資訊的平臺,更是一個互動性、視覺吸引力和功能性兼具的數位體驗。而CSS(Cascading Style Sheets)正是網站設計中的一個重要元素,扮演著關鍵的角色。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
CSS 的繼承性是開發網頁樣式時的一個重要概念,它使得樣式設計更加靈活和高效,有助於提高程式碼的可讀性、一致性和可重用性,並加快開發速度,從而提供更好的開發體驗。
前言 終於要到這個振奮人心的章節了,我們終於要來學習,如何讓自己的網頁更加美觀。 但在這之前,我們肯定得先學習,如何將我們的 CSS 檔案,連接到 HTML 當中。 連結分類 首先,我們在連結 CSS 的方法中,有分為三種: 內聯連結 在 .html 當中,任一標籤的裡面,用屬性 s
Thumbnail
在 CSS 的開發過程中,重複使用如顏色、字體大小等值是常見的需求。為了提高程式碼維護性和靈活性,就需要用到 CSS 變量了,CSS 變量可以讓你在樣式表中儲存可重用的值。本文將介紹 CSS 變量的概念、使用方法,以及它對撰寫 CSS 的影響。
Thumbnail
如何透過 CSS 來美化和增強文本的可讀性,對於提升用戶體驗至關重要。本文將介紹如何使用 CSS 來處理網頁上的文本,包括字型設定、文本排列、裝飾等多方面。
Thumbnail
您對前端有興趣,對CSS不陌生。CSS新特性前應瞭解基本內容。CSS屬性制定經歷過程,瀏覽器私有前綴及處理,開發者對新特性漸進增強,優雅降級處理,Web標準定義、作用等。
Thumbnail
在這一章中,我們介紹了 CSS 的過渡效果和動畫效果。過渡效果使 CSS 屬性的變化更加平滑,而動畫效果則允許我們更精細地控制元素的多個屬性隨時間變化的過程。我們通過基本語法和示例展示了如何使用這些效果,並提供了一個綜合應用的實踐案例來幫助理解。這些技術可以讓你的網頁更具互動性和動態效果。
Thumbnail
這節課的學習目標是了解 CSS 的基本語法結構和使用方法。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
在當今日新月異的數位時代,網站已經不僅僅是一個給人們提供資訊的平臺,更是一個互動性、視覺吸引力和功能性兼具的數位體驗。而CSS(Cascading Style Sheets)正是網站設計中的一個重要元素,扮演著關鍵的角色。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
CSS 的繼承性是開發網頁樣式時的一個重要概念,它使得樣式設計更加靈活和高效,有助於提高程式碼的可讀性、一致性和可重用性,並加快開發速度,從而提供更好的開發體驗。
前言 終於要到這個振奮人心的章節了,我們終於要來學習,如何讓自己的網頁更加美觀。 但在這之前,我們肯定得先學習,如何將我們的 CSS 檔案,連接到 HTML 當中。 連結分類 首先,我們在連結 CSS 的方法中,有分為三種: 內聯連結 在 .html 當中,任一標籤的裡面,用屬性 s
Thumbnail
在 CSS 的開發過程中,重複使用如顏色、字體大小等值是常見的需求。為了提高程式碼維護性和靈活性,就需要用到 CSS 變量了,CSS 變量可以讓你在樣式表中儲存可重用的值。本文將介紹 CSS 變量的概念、使用方法,以及它對撰寫 CSS 的影響。
Thumbnail
如何透過 CSS 來美化和增強文本的可讀性,對於提升用戶體驗至關重要。本文將介紹如何使用 CSS 來處理網頁上的文本,包括字型設定、文本排列、裝飾等多方面。
Thumbnail
您對前端有興趣,對CSS不陌生。CSS新特性前應瞭解基本內容。CSS屬性制定經歷過程,瀏覽器私有前綴及處理,開發者對新特性漸進增強,優雅降級處理,Web標準定義、作用等。