TailwindCSS v4 全新颜色系统与主题切换
该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/tech/tailwindcss-v4-color-system-theme-switching-guide
在这之前
在很久的时候我写过一篇文章使用一种便捷的方式去实现 dark mode 的颜色切换,简单来说就是用 CSS 变量实现的,替换了默认的所有的颜色色值。
https://innei.in/posts/programming/tailwind-built-in-colors-dark-mode
这样虽然也可以实现,但是局限性比较多,比如为了让颜色支持 Tailwindcss 的 /<alpha>
的语法,我们在定义颜色的时候得这样写:
module.exports = {
theme: {
colors: {
"material-opaque": "rgb(var(--color-materialOpaque) / <alpha-value>)",
},
},
}
此时的 CSS 变量的值并不是一个颜色值,而是一个字符串:
--color-materialOpaque-light: 246 246 246;
不仅在编辑器中无法直接看到颜色的呈现,修改起来也是难事。
最大的问题,如果设定的颜色本身带有透明度,那么 /<alpha>
的语法直接失效:
module.exports = {
theme: {
colors: {
"material-ultra-thin-light": "rgba(var(--color-materialUltraThin-light))",
},
},
}
/// CSS
--color-materialUltraThick-light: 246 246 246 / 0.84;
因为 CSS 颜色引用了透明度,将无法应用两次透明度。这直接导致 bg-material-ultra-thin-light/10
失效。
color-mix
是什么
在 TailwindCSS 4 中,不在使用原先的方式去调整透明度,而是改用 color-mix()
color-mix()
函数标记接收两个 <color>
值,并返回在指定颜色空间、指定数量混合后的颜色。
它是支持多种颜色进行混合的,那么对于本身是透明的颜色,也可以再进行一次混合。
在 TailwindCSS v4 中是这样调整透明度的。
bg-background-secondary/30
↓
color-mix(in oklab, var(--color-background-secondary) /* oklch(0.98 0.0049 230) = #f5f9fb */ 30%, transparent);
通过混色一个 transparent,控制 transparent 的深度来实现最终的透明。
对于本身就存在透明的颜色也是没有问题的:
.bg-material-thin\/20 {
background-color: color-mix(in oklab, var(--color-material-thin) /* oklch(0.96 0.0049 230 / 0.60) = #eff2f499 */ 20%, transparent);
}
@layer
层级控制场景下的颜色
在 TailwindCSS v4 之前的版本,也已经大量使用 @layer
来控制 className 的优先级问题,但是这个声明都是 polyfill 的,在 PostCSS 中进行转义,实际在应用中并不会出现这个 layer。
在 V4 之后的版本中,已经默认使用 layer 控制层级。v4 和 v3 之前的版本最大的不同,就是 v4 不再需要在 js config 中定义新的颜色或者覆写自带的颜色。而是全部通过 CSS 实现的,这也是得益于 layer 的优势。在 TailwindCSS 所有定义都在 @layer theme
中,我们只需要在不同的时候覆写其变量值就可以了。
那么下面就是一个简单的例子,我们需要自动切换 light/dark,支持当 data-theme='cute' 时切换主题颜色到 cute 的颜色风格。
@import "tailwindcss";
/* Light mode colors (default) */
@theme {
--color-blue: oklch(0.65 0.18 237);
--color-pink: oklch(0.68 0.22 350);
--color-purple: oklch(0.65 0.2 280);
--color-green: oklch(0.67 0.15 155);
--color-orange: oklch(0.68 0.15 60);
--color-yellow: oklch(0.75 0.12 100);
}
首先使用 @theme
定义 TailwindCSS 颜色。@theme
在 浏览器中也是应用在 @layer theme
中,其目的让 TailwindCSS 识别配置。
然后控制在当 dark:
作用下的颜色:
@layer theme {
* {
/* Dark mode overrides */
@variant dark {
--color-blue: oklch(0.7 0.16 237);
--color-pink: oklch(0.73 0.2 350);
--color-purple: oklch(0.7 0.18 280);
--color-green: oklch(0.72 0.16 155);
--color-orange: oklch(0.73 0.16 60);
--color-yellow: oklch(0.78 0.14 100);
}
}
这里注意了,写成 @layer theme
而不是 @theme
因为这个是在浏览器中覆写的,而不是 TailwindCSS 的配置。
最后实现另类主题,我们可通过 data-theme
控制:
@layer theme {
[data-theme=cute] * {
/* Kawaii color overrides */
--color-blue: oklch(0.85 0.12 237);
--color-pink: oklch(0.87 0.16 350);
--color-purple: oklch(0.84 0.14 280);
--color-green: oklch(0.85 0.12 155);
--color-orange: oklch(0.86 0.12 60);
--color-yellow: oklch(0.9 0.1 100);
}
/* Kawaii dark mode overrides */
@variant dark {
--color-blue: oklch(0.65 0.14 237);
--color-pink: oklch(0.7 0.18 350);
--color-purple: oklch(0.67 0.16 280);
--color-green: oklch(0.68 0.14 155);
--color-orange: oklch(0.69 0.14 60);
--color-yellow: oklch(0.73 0.12 100);
}
}
同样另类主题也要适配 dark:
颜色适配。
至此我们实现了四套颜色的无缝切换。效果非常的好,在编辑器中也可以直接查看色值:
对比之前 V3 因为是变量,什么都看不到。而 V4 本身配置下的颜色就是变量,所以可以直接看到颜色了。
结语
什么,你问这么好用的现代的 TailwindCSS V4 的颜色系统库在能哪里找到。那必须是我最新写的 Pastel。
https://github.com/Innei/Pastel
还不知道这个的赶快去点 Star,然后替换颜色定义!