Tailwind CSS v4 主題化實踐入門(自定義 Theme + 主題模式切換)?

ok,經過學習Tailwindcss我決定將此專欄建設成為一個Tailwindcss實戰專欄,我將在專欄內完成5050挑戰:50天50個Tailwindcss練習項目,歡迎大家訂閱!!!

Tailwind CSS v4 帶來了更強大的主題定制能力,給了前端開發者更加靈活的設計空間。
今天,我們將來學習 Tailwind CSS v4 的主題相關特性,并且給出一套實踐模板 🚀

主題相關核心 API 介紹

Tailwind v4 主題使用 @theme 定義,并支持直接使用 CSS 變量來簡化主題設計。下面是官方文檔鏈接:

  • 主題變量
  • 添加自定義樣式
  • 函數和指令

下面介紹集中常見的主題相關的指令以及自定義變體。

1. @theme 元素

Tailwind v4 引入 @theme 用來定義 CSS 變量,與v3版本需要在 tailwind.config.js 里配置相比,更為簡潔統一。

@theme {--color-primary: var(--primary);--radius-md: calc(var(--radius) - 2px);
}

2. @custom-variant

Tailwind v4 支持自定義優先級,實現更靈活的 dark mode 、 sidebar mode 等 UI 體驗的切換。

@custom-variant dark (&:is(.dark *));

定義了一個名為 dark 的自定義變體,它會匹配所有帶有 .dark 類的元素內部的所有元素。

3. @layer

雖然 Tailwind 能滿足大部分樣式需求,但有時候還是需要編寫純 CSS。這時,@layer指令就登場了!

  • 使用 @layer 指令告訴 Tailwind 一組自定義樣式屬于哪個 bucket。有效圖層為 basecomponentsutilities
    • 三個圖層的生效順序是不一致的,作用在同一元素上的相同的樣式屬性,生效優先級順序是:utilities > components >base
  • 使用 @apply 將任何現有工具類內聯到你自己的自定義 CSS 中
  • 你仍然可以在你的css文件中寫出任何原生的css樣式,但是通常不建議這么做,這會增加維護難度。
@layer base {body {@apply bg-background text-foreground;}
}@layer components {card {@apply bg-card text-card-foreground;}
}@layer utilities {.heading {@apply text-4xl font-bold;}
}

利用Theme 實現主題切換

我們可以通過 :root.dark 樣式規則來分別定義不同主題模式下的 變量 值,然后配合 @theme 以及 自定義變體 展開 Tailwind 內部設計。

@custom-variant dark (&:is(.dark *));@theme {--color-background: var(--background);--color-foreground: var(--foreground);--color-card: var(--card);--color-card-foreground: var(--card-foreground);--color-popover: var(--popover);--color-popover-foreground: var(--popover-foreground);--color-primary: var(--primary);--color-primary-foreground: var(--primary-foreground);--color-secondary: var(--secondary);--color-secondary-foreground: var(--secondary-foreground);--color-muted: var(--muted);--color-muted-foreground: var(--muted-foreground);--color-accent: var(--accent);--color-accent-foreground: var(--accent-foreground);--color-destructive: var(--destructive);--color-destructive-foreground: var(--destructive-foreground);--color-border: var(--border);--color-input: var(--input);--color-ring: var(--ring);--color-chart-1: var(--chart-1);--color-chart-2: var(--chart-2);--color-chart-3: var(--chart-3);--color-chart-4: var(--chart-4);--color-chart-5: var(--chart-5);--radius-sm: calc(var(--radius) - 4px);--radius-md: calc(var(--radius) - 2px);--radius-lg: var(--radius);--radius-xl: calc(var(--radius) + 4px);--color-sidebar: var(--sidebar);--color-sidebar-foreground: var(--sidebar-foreground);--color-sidebar-primary: var(--sidebar-primary);--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);--color-sidebar-accent: var(--sidebar-accent);--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);--color-sidebar-border: var(--sidebar-border);--color-sidebar-ring: var(--sidebar-ring);
}:root {--background: oklch(1 0 0);--foreground: oklch(0.145 0 0);--card: oklch(1 0 0);--card-foreground: oklch(0.145 0 0);--popover: oklch(1 0 0);--popover-foreground: oklch(0.145 0 0);--primary: oklch(0.205 0 0);--primary-foreground: oklch(0.985 0 0);--secondary: oklch(0.97 0 0);--secondary-foreground: oklch(0.205 0 0);--muted: oklch(0.97 0 0);--muted-foreground: oklch(0.556 0 0);--accent: oklch(0.97 0 0);--accent-foreground: oklch(0.205 0 0);--destructive: oklch(0.577 0.245 27.325);--destructive-foreground: oklch(0.577 0.245 27.325);--border: oklch(0.922 0 0);--input: oklch(0.922 0 0);--ring: oklch(0.708 0 0);--chart-1: oklch(0.646 0.222 41.116);--chart-2: oklch(0.6 0.118 184.704);--chart-3: oklch(0.398 0.07 227.392);--chart-4: oklch(0.828 0.189 84.429);--chart-5: oklch(0.769 0.188 70.08);--radius: 0.625rem;--sidebar: oklch(0.985 0 0);--sidebar-foreground: oklch(0.145 0 0);--sidebar-primary: oklch(0.205 0 0);--sidebar-primary-foreground: oklch(0.985 0 0);--sidebar-accent: oklch(0.97 0 0);--sidebar-accent-foreground: oklch(0.205 0 0);--sidebar-border: oklch(0.922 0 0);--sidebar-ring: oklch(0.708 0 0);
}.dark {--background: oklch(0.145 0 0);--foreground: oklch(0.985 0 0);--card: oklch(0.145 0 0);--card-foreground: oklch(0.985 0 0);--popover: oklch(0.145 0 0);--popover-foreground: oklch(0.985 0 0);--primary: oklch(0.985 0 0);--primary-foreground: oklch(0.205 0 0);--secondary: oklch(0.269 0 0);--secondary-foreground: oklch(0.985 0 0);--muted: oklch(0.269 0 0);--muted-foreground: oklch(0.708 0 0);--accent: oklch(0.269 0 0);--accent-foreground: oklch(0.985 0 0);--destructive: oklch(0.396 0.141 25.723);--destructive-foreground: oklch(0.637 0.237 25.331);--border: oklch(0.269 0 0);--input: oklch(0.269 0 0);--ring: oklch(0.439 0 0);--chart-1: oklch(0.488 0.243 264.376);--chart-2: oklch(0.696 0.17 162.48);--chart-3: oklch(0.769 0.188 70.08);--chart-4: oklch(0.627 0.265 303.9);--chart-5: oklch(0.645 0.246 16.439);--sidebar: oklch(0.205 0 0);--sidebar-foreground: oklch(0.985 0 0);--sidebar-primary: oklch(0.488 0.243 264.376);--sidebar-primary-foreground: oklch(0.985 0 0);--sidebar-accent: oklch(0.269 0 0);--sidebar-accent-foreground: oklch(0.985 0 0);--sidebar-border: oklch(0.269 0 0);--sidebar-ring: oklch(0.439 0 0);
}
... 其他主題樣式

最佳實踐:切換主題按鈕組件

下面是我創建的用于切換主題的按鈕組件,大家可以參考一下:

<template><button@click="toggleTheme"class="flex items-center gap-2 rounded bg-gray-200 px-4 py-2 text-gray-800 transition-colors duration-300 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-100 dark:hover:bg-gray-600"><span v-if="isDark">🌙 暗黑</span><span v-else>?? 亮色</span></button>
</template><script setup>import { ref, onMounted } from 'vue'const isDark = ref(false)const toggleTheme = () => {isDark.value = !isDark.valuedocument.documentElement.classList.toggle('dark')localStorage.setItem('theme', isDark.value ? 'dark' : 'light')}onMounted(() => {const theme = localStorage.getItem('theme')isDark.value = theme === 'dark'if (isDark.value) {document.documentElement.classList.add('dark')}})
</script>

其他

當然tailwindcss v4支持豐富的 自定義樣式 復雜樣式 以及 自定義變體,今天們探討一些常用的主題配置和規則。

Tailwind CSS v4 主題相關引入,讓你從分散的屬性處理升級到全局統一。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79909.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79909.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79909.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SAF利用由Varjo和AFormX開發的VR/XR模擬器推動作戰訓練

通過將AFormX的先進軍用飛行模擬器與Varjo的行業領先的VR/XR硬件相結合&#xff0c;斯洛文尼亞武裝部隊正以經濟高效、沉浸式的訓練方式培訓戰斗機飛行員&#xff0c;以提高其戰術準備和作戰效率。 挑戰&#xff1a;獲得戰術軍事航空訓練的機會有限 軍事航空訓練長期以來一直…

VUE中通過DOM導出PDF

最終效果 前端導出PDF的核心在于樣式的繪制上&#xff0c;這里其實直接使用CSS進行繪制和布局就行&#xff0c;只不過需要計算好每頁DIV盒子的大小&#xff0c;防止一頁放不下造成樣式錯亂。 項目依賴 項目是Vue3 TS npm i html2canvas1.4.1 npm i jspdf3.0.1工具類(htmlToPdf…

SpringAI框架中的RAG模塊詳解及應用示例

SpringAI框架中的RAG模塊詳解及應用示例 RAG&#xff08;Retrieval-Augmented Generation&#xff09;可以通過檢索知識庫&#xff0c;克服大模型訓練完成后參數凍結的局限性&#xff0c;攜帶知識讓大模型根據知識進行回答。SpringAI框架提供了模塊化的API來支持RAG&#xff0…

MySQL-數據查詢(測試)-05-(12-1)

1-數據準備&#xff1a; CREATE TABLE 員工信息表 (員工編號 VARCHAR(10) PRIMARY KEY,姓名 VARCHAR(20),學歷 VARCHAR(20),出生日期 DATE,性別 INT,工作年限 INT,地址 VARCHAR(100),電話號碼 VARCHAR(20),員工部門號 INT ); INSERT INTO 員工信息表 (員工編號, 姓名, 學歷, 出…

5G網絡:能源管理的“智能電網“革命,Python如何成為關鍵推手?

5G網絡:能源管理的"智能電網"革命,Python如何成為關鍵推手? 大家好,我是Echo_Wish。今天咱們聊一個既硬核又接地氣的話題——5G網絡如何用Python代碼重構全球能源管理。 不知道你們有沒有注意過: ? 家里裝了智能電表后,電費突然變"聰明"了,谷時充…

AI背景下,如何重構你的產品?

當AI敲門時&#xff0c;你的產品準備好開門了嗎&#xff1f; 最近和做產品的老張聊天&#xff0c;他愁眉苦臉地說&#xff1a;"現在AI這么火&#xff0c;我們的產品就像個老古董&#xff0c;用戶都跑隔壁用AI產品去了。“這話讓我想起三年前另一個朋友&#xff0c;當時區…

互聯網大廠Java面試實戰:從Spring Boot到微服務的技術問答與解析

&#x1f4aa;&#x1f3fb; 1. Python基礎專欄&#xff0c;基礎知識一網打盡&#xff0c;9.9元買不了吃虧&#xff0c;買不了上當。 Python從入門到精通 &#x1f601; 2. 畢業設計專欄&#xff0c;畢業季咱們不慌忙&#xff0c;幾百款畢業設計等你選。 ?? 3. Python爬蟲專欄…

Apollo學習——aem問題

執行aem指令出現一下問題 lxflxf:~/MYFile/apollo_v10.0 $aem enter permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.49/containers/json?filters%7B%22name%22%…

數字IC后端零基礎入門基礎理論(Day2)

數字IC后端零基礎入門基礎理論&#xff08;Day1&#xff09; Placement Blockage: cell擺放阻擋層。它是用來引導工具做placement的一種物理約束或手段&#xff0c;目的是希望工具按照我們的要求來做標準單元的擺放。 它主要有三種類型&#xff0c;分別是hard placement bloc…

如何遠程執行腳本不留痕跡

通常我們在做遠程維護的時候&#xff0c;會有這么一個需求&#xff0c;就是我想在遠程主機執行一個腳本&#xff0c;但是這個腳本我又不想保留在遠程主機上&#xff0c;那么有人就說了&#xff0c;那就復制過去再登錄遠程執行不就行了嗎&#xff1f;嗯嗯&#xff0c;但是這還不…

【Lua】java 調用redis執行 lua腳本

【Lua】java 調用redis執行 lua腳本 public Object executeLuaScript(String script, List<String> keys, Object... args) {// 注意: 這里 Long.class 是返回值類型, 一定要指定清楚 不然會報錯return this.redisTemplate.execute(RedisScript.of(j腳本, Long.class), k…

利用混合磁共振成像 - 顯微鏡纖維束成像技術描繪結構連接組|文獻速遞-深度學習醫療AI最新文獻

Title 題目 Imaging the structural connectome with hybrid MRI-microscopy tractography 利用混合磁共振成像 - 顯微鏡纖維束成像技術描繪結構連接組 01 文獻速遞介紹 通過多種模態繪制大腦結構能夠增進我們對大腦功能、發育、衰老以及疾病的理解&#xff08;漢森等人&am…

Shell腳本實踐(修改文件,修改配置文件,執行jar包)

1、前言 需要編寫一個shell腳本支持 1、修改.so文件名 2、修改配置文件 3、執行jar包 2、代碼解析 2.1、修改.so文件名 so_file_dir="/opt/casb/xxx/lib" # 處理.so文件 cd "$so_file_dir" || { echo "錯誤: 無法進入目錄 $so_file_dir"; exit …

基于GPUGEEK 平臺進行深度學習

一、平臺簡介 GPUGEEK 是一個專注于提供 GPU 算力租賃服務的平臺&#xff0c;在人工智能與深度學習領域為用戶搭建起便捷的算力橋梁。它整合了豐富多樣的 GPU 資源&#xff0c;涵蓋 RTX - 4090、RTX - 3090、A100 - PCIE 等多種型號&#xff0c;滿足不同用戶在模型訓練、數據處…

Android Framework學習五:APP啟動過程原理及速度優化

文章目錄 APP啟動優化概述APP啟動流程點擊圖片啟動APP的過程啟動觸發Zygote 與應用進程創建Zygote進程的創建應用進程初始化 ApplicationActivity 啟動與顯示 優化啟動時黑白屏現象可優化的階段Application階段相關優化 Activity階段數據加載階段 Framework學習系列文章 APP啟動…

Web 實時通信技術:WebSocket 與 Server-Sent Events (SSE) 深入解析

一、WebSocket&#xff1a; &#xff08;一&#xff09;WebSocket 是什么&#xff1f; WebSocket 是一種網絡通信協議&#xff0c;它提供了一種在單個 TCP 連接上進行全雙工通信的方式。與傳統的 HTTP 請求 - 響應模型不同&#xff0c;WebSocket 允許服務器和客戶端在連接建立…

MySQL(8)什么是主鍵和外鍵?

主鍵&#xff08;Primary Key&#xff09;和外鍵&#xff08;Foreign Key&#xff09;是關系數據庫中用于定義和維護表之間關系的重要概念。以下是詳細的解釋、示例代碼和操作步驟。 主鍵&#xff08;Primary Key&#xff09; 定義 主鍵是表中的一個或多個字段&#xff0c;其…

任意復雜度的 JSON 數據轉換為多個結構化的 Pandas DataFrame 表格

以下是一個 完整、結構清晰、可運行的 Python 工具&#xff0c;用于將任意復雜度的 JSON 數據轉換為多個結構化的 Pandas DataFrame 表格。該工具支持嵌套對象、嵌套數組&#xff0c;并通過主鍵和外鍵建立表之間的關聯關系。 if __name__ "__main__":# 示例 JSON 數…

【SSL部署與優化?】??HTTP/2與HTTPS的協同效應

HTTP/2與HTTPS的協同效應&#xff1a;為何HTTP/2強制要求TLS 1.2&#xff1f; HTTP/2是HTTP協議的現代升級版&#xff0c;旨在通過多路復用、頭部壓縮等技術提升性能。然而&#xff0c;HTTP/2的設計與部署與HTTPS&#xff08;TLS加密&#xff09;緊密相關&#xff0c;甚至強制…

爬蟲請求頻率應控制在多少合適?

爬蟲請求頻率的控制是一個非常重要的問題&#xff0c;它不僅關系到爬蟲的效率&#xff0c;還涉及到對目標網站服務器的影響以及避免被封禁的風險。合理的請求頻率需要根據多個因素來綜合考慮&#xff0c;以下是一些具體的指導原則和建議&#xff1a; 一、目標網站的政策 查看網…