善用 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


3會員
5Content count
我是Sail,這裡主要分享一些自己覺得有趣的前端議題。
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
「同學們,我被診斷出糖尿病了,大家也要注意身體啊!」阿德在大學同學的群組上留言寫道:「可能是太常熬夜又不運動,畢業十年就胖了20幾公斤。」 一看到訊息,同學們紛紛留言: 「我們還不到35歲,原來也會得糖尿病啊!」 「唉…我都不敢去檢查!」 「你有什麼症狀嗎?」
Thumbnail
Twitter 用戶 《The DeFi Edge (DeFi 研究員)》,他在二月份時,發了一篇長文推文,解釋了《德州撲克》的博弈策略、心態,而且與《加密貨幣》作為對比。這樣的類比感覺非常有趣,或許也間接解釋,為何《加密貨幣大佬》有些甚至是撲克高手。
Thumbnail
越來越多的優秀企業開始關注員工的各種高層次需要,從而鼓勵、支援並幫助員工實現其職業乃至人生的抱負。企業既期待員工能夠積極與企業共同發展,同時也意識到,要想吸引並留住頂尖人才,需要打造差異化的企業職場體驗。 視角一:新時代的職場人,人人都是體驗者 視角二:創造員工體驗成為人才管理的新熱點
Thumbnail
為了解決心中的諸多疑惑,很多人都會上網搜尋資料,希望能找到對自己有幫助的解答。 許多高中生與家長都會搜尋「學習歷程是什麼」、「學習歷程怎麼寫」、「學習歷程 教授想看什麼」,接著就會跑出成千上萬、五花八門的網路資訊,通常從第一欄搜尋結果開始點閱,然後一直往下瀏覽,可能翻了好幾頁的搜尋結果也無法真正解惑
Thumbnail
I,CV 和 Resume 是一樣的內容嗎? 履歷 (Curriculum Vitae) 是拉丁語,意思是 "人生的歷程"。 相比之下,Resume (簡歷)在法語中是 "Summary"的意思。 CV(履歷)涵蓋了全部學經歷,還包括得獎、出版品、其他作品、社團會員等等,因此文件的長度較長; 相比之
Thumbnail
善用DECAX模式,有效擬定您的內容行銷策略 話說從事網路行銷的朋友,想必對AIDMA模式和AISAS模式都不陌生吧? 所謂的AIDMA模式,其實是1920年代美國行銷廣告專家山姆.羅蘭.霍爾(Samuel Roland Hall)在其著作中,闡述廣告宣傳對消費者心理過程的縮寫。 AIDMA模式,表
Thumbnail
「矮要承認打要站穩」,這句話硬要搬到摩托賽車這邊講的話,可以講成「姿勢要矮下盤要穩」,不過其實....所有的運動都是一樣的 就像籃球,進入纏鬥時一定是兩腳彎曲彎曲上身前屈 武道方面,跆拳空手道不管是馬步還是三七步,也都是把重心放低,摩托賽車也是一種激烈運動,要好好控制車子的話,下盤也是一大關鍵 雖
什麼是網路行銷? 網路行銷也稱為數位行銷,是使用有助於推動流量,潛在客戶和銷售的工具在互聯網上推廣企業或品牌及其產品或服務的過程。 內容行銷 注重產生有質量的和幫助性的文章,關鍵就是製造“有價值的”的內容。 正是這種定義與幾乎可以描述任何形式的廣告或營銷的定義有所不同。 您可以判斷某段內容是否屬於內
Thumbnail
這一兩天大家應該都有看到女模命案大逆轉的新聞吧!一直以來筆者在網路發言都非常小心,一方面盡量不要人身攻擊,另一方面也會等到事情真正水落石出之後,再下評論也不遲,因為人很容易用直覺來判斷事情,再加上各家媒體如果都報導類似內容的話,會讓人產生好像真的有這麼一回事錯覺,風向就這樣被帶過去了,所以常常都會
Thumbnail
據統計,我們的孩子們愈來愈不快樂,壓力愈來愈大,又找不到正確舒解壓力的管道,我想,或許跟我們的孩子愈來愈缺乏會流汗的運動(或遊戲)有關。
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
「同學們,我被診斷出糖尿病了,大家也要注意身體啊!」阿德在大學同學的群組上留言寫道:「可能是太常熬夜又不運動,畢業十年就胖了20幾公斤。」 一看到訊息,同學們紛紛留言: 「我們還不到35歲,原來也會得糖尿病啊!」 「唉…我都不敢去檢查!」 「你有什麼症狀嗎?」
Thumbnail
Twitter 用戶 《The DeFi Edge (DeFi 研究員)》,他在二月份時,發了一篇長文推文,解釋了《德州撲克》的博弈策略、心態,而且與《加密貨幣》作為對比。這樣的類比感覺非常有趣,或許也間接解釋,為何《加密貨幣大佬》有些甚至是撲克高手。
Thumbnail
越來越多的優秀企業開始關注員工的各種高層次需要,從而鼓勵、支援並幫助員工實現其職業乃至人生的抱負。企業既期待員工能夠積極與企業共同發展,同時也意識到,要想吸引並留住頂尖人才,需要打造差異化的企業職場體驗。 視角一:新時代的職場人,人人都是體驗者 視角二:創造員工體驗成為人才管理的新熱點
Thumbnail
為了解決心中的諸多疑惑,很多人都會上網搜尋資料,希望能找到對自己有幫助的解答。 許多高中生與家長都會搜尋「學習歷程是什麼」、「學習歷程怎麼寫」、「學習歷程 教授想看什麼」,接著就會跑出成千上萬、五花八門的網路資訊,通常從第一欄搜尋結果開始點閱,然後一直往下瀏覽,可能翻了好幾頁的搜尋結果也無法真正解惑
Thumbnail
I,CV 和 Resume 是一樣的內容嗎? 履歷 (Curriculum Vitae) 是拉丁語,意思是 "人生的歷程"。 相比之下,Resume (簡歷)在法語中是 "Summary"的意思。 CV(履歷)涵蓋了全部學經歷,還包括得獎、出版品、其他作品、社團會員等等,因此文件的長度較長; 相比之
Thumbnail
善用DECAX模式,有效擬定您的內容行銷策略 話說從事網路行銷的朋友,想必對AIDMA模式和AISAS模式都不陌生吧? 所謂的AIDMA模式,其實是1920年代美國行銷廣告專家山姆.羅蘭.霍爾(Samuel Roland Hall)在其著作中,闡述廣告宣傳對消費者心理過程的縮寫。 AIDMA模式,表
Thumbnail
「矮要承認打要站穩」,這句話硬要搬到摩托賽車這邊講的話,可以講成「姿勢要矮下盤要穩」,不過其實....所有的運動都是一樣的 就像籃球,進入纏鬥時一定是兩腳彎曲彎曲上身前屈 武道方面,跆拳空手道不管是馬步還是三七步,也都是把重心放低,摩托賽車也是一種激烈運動,要好好控制車子的話,下盤也是一大關鍵 雖
什麼是網路行銷? 網路行銷也稱為數位行銷,是使用有助於推動流量,潛在客戶和銷售的工具在互聯網上推廣企業或品牌及其產品或服務的過程。 內容行銷 注重產生有質量的和幫助性的文章,關鍵就是製造“有價值的”的內容。 正是這種定義與幾乎可以描述任何形式的廣告或營銷的定義有所不同。 您可以判斷某段內容是否屬於內
Thumbnail
這一兩天大家應該都有看到女模命案大逆轉的新聞吧!一直以來筆者在網路發言都非常小心,一方面盡量不要人身攻擊,另一方面也會等到事情真正水落石出之後,再下評論也不遲,因為人很容易用直覺來判斷事情,再加上各家媒體如果都報導類似內容的話,會讓人產生好像真的有這麼一回事錯覺,風向就這樣被帶過去了,所以常常都會
Thumbnail
據統計,我們的孩子們愈來愈不快樂,壓力愈來愈大,又找不到正確舒解壓力的管道,我想,或許跟我們的孩子愈來愈缺乏會流汗的運動(或遊戲)有關。