前言 {#前言}
tailwindcss
是有一个什么Dark Mode 的,但是我觉得这个,不够用,也不好用。翻了网上的一些方法,发现还是css变量的方式更加好用,在这里做个记录。
思路 {#思路}
首先,我们按照正常的思路来,想要实现网页的主题切换。我们只需要准备几套配色,然后在切换相应的标记来应用即可,非常简单,就如非常常见的html
标签上的data-scheme="light"
等,下面我用的是body
的类名来切换。
定义变量 {#定义变量}
在你自己的tailwind.css
中定义即可,直接看代码:
@tailwind base;
@tailwind components;
@tailwind utilities;
`@layer base {
.light {
--bg-base: #f8fafc;
--bg-primary: #ffffff;
--bg-secondary: #111;
--text-base: #757575;
--text-active: #50a1ff;
}
.fugu {
--bg-base: #f2efdd;
--bg-primary: #f7f5ea;
--bg-secondary: #eeebd4;
--text-base: rgba(17,19,14,.7);
--text-active: #baaa49;
}
.huyan {
--bg-base: #c7ebca;
--bg-primary: #d4f0d6;
--bg-secondary: #bee8c1;
--text-base: rgba(16,20,16,.7);
--text-active: #3da946;
}
.haitian {
--bg-base: #dce2f1;
--bg-primary: #e9edf6;
--bg-secondary: #d3daed;
--text-base: rgba(16,20,16,.7);
--text-active: #4a69b7;
}
.dark {
--bg-base: #16202f;
--bg-primary: #1c283b;
--bg-secondary: #121a26;
--text-base: rgba(160,180,200,.9);
--text-active: #50a1ff;
}
.black {
--bg-base: #171717;
--bg-primary: #202020;
--bg-secondary: #111;
--text-base: #d4d4d5;
--text-active: #50a1ff;
}
}
`
@layer base {}
中正常定义即可
config 应用 {#config-应用}
接下来修改在tailwind.config
中的配置,以使用:
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue",
],
theme: {
extend: {
backgroundColor: {
'base': 'var(--bg-base)',
'primary': 'var(--bg-primary)',
'secondary': 'var(--bg-secondary)',
},
textColor: {
'base': 'var(--text-base)',
'active': 'var(--text-active)',
},
},
`},
plugins: [],
}
`
修改内容就是theme.extend
里面的配置,例如backgroundColor
中设置了三个自定义变量,随后就可以在页面中使用bg-base
应用。
可以看到,这也是直接就有代码提示的。Tailwind
中有个样式是text-opacity-10
设置了字体颜色,还可以设置透明度。
.text-gray-900 {
--tw-text-opacity: 1;
color: rgba(17,24,39,var(--tw-text-opacity));
}
如想要支持这个透明度的样式,我们还需要将颜色转成Rgb,tailwind.config.js
配置
/** @type {import('tailwindcss').Config} */
function withOpacity(variableName) {
return ({ opacityValue }) =\> {
if (opacityValue) {
return `rgba(var(${variableName}), ${opacityValue})`;
}
return `rgb(var(${variableName}))`;
};
}
`export default {
content: [
"./components/`/*.{js,vue,ts}",
"./layouts/`/`.vue",
"./pages/**/`.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue",
],
theme: {
extend: {
backgroundColor: {
'base': withOpacity('var(--bg-base)'),
},
},
},
plugins: [],
}
`
效果 {#效果}
<script setup lang="ts">
const changeTheme = (theme: string) => {
document.body.classList.remove('light', 'fugu', 'huyan', 'haitian', 'dark', 'black')
document.body.classList.add(theme)
}
\</script\>
\<template\>
\<div class="bg-p"\>
\<slot /\>
\<div class="bg-green-400 flex flex-row justify-center"\>
\<button class="basis-1/6" @click="changeTheme('light')"\>明亮\</button\>
\<button class="basis-1/6" @click="changeTheme('fugu')"\>复古\</button\>
\<button class="basis-1/6" @click="changeTheme('huyan')"\>护眼\</button\>
\<button class="basis-1/6" @click="changeTheme('haitian')"\>海天\</button\>
\<button class="basis-1/6" @click="changeTheme('dark')"\>深邃\</button\>
\<button class="basis-1/6" @click="changeTheme('black')"\>暗黑\</button\>
\</div\>
\</div\>
\</template\>
\<style scoped\>
`</style>
`
这里简单加了几个按钮用来修改类。
<div class="w-full">
<div class="w-full h-[50px] bg-base">
'base': 'var(--bg-base)',
</div>
<div class="w-full h-[50px] bg-primary">
'primary': 'var(--bg-primary)',
</div>
<div class="w-full h-[50px] bg-secondary">
'secondary': 'var(--bg-secondary)',
</div>
<div class="w-full h-[50px] text-base">
'base': 'var(--text-base)',
</div>
<div class="w-full h-[50px] text-active font-bold">
'active': 'var(--text-active)',
</div>
`</div>
`
然后简单在页面展示一下。就可以得到一下效果。
现在想要的效果已经达到了。非常的简单。