-
prefers-color-scheme: 这是浏览器自带的功能,它会自动检测你的 Windows、macOS、iOS 或 Android 系统当前是处于“浅色”还是“深色”模式。 -
CSS Selector (CSS 选择器) : 在 Tailwind 中,如果你开启了手动模式,通常会在 HTML 的根元素(
<html>)上添加一个.dark类。- 自动模式:系统变黑 网站变黑。
- 手动模式:HTML 标签变为
<html class="dark">网站变黑(无论系统设置如何)。
手动设置Dark模式
1. 声明自定义变体 (CSS 配置)
首先,你需要在 CSS 文件中告诉 Tailwind:不要再根据系统设置(媒体查询)来触发深色样式了,改为根据 HTML 中的 .dark 类名来触发。
在 app.css 中添加:
@import "tailwindcss";
/* 定义:只要当前元素或其祖先节点有 .dark 类,就启用 dark: 样式 */
@custom-variant dark (&:where(.dark, .dark *));
2. 结构准备 (HTML 结构)
在 HTML 结构中,你需要一个“开关”来手动控制根元素(通常是 <html>)的类名。
<html id="root-html" class="">
<body class="bg-white dark:bg-black text-black dark:text-white">
<button id="theme-toggle">切换模式</button>
</body>
</html>
Tailwind 的解决方案:变量堆叠
Tailwind 并不是直接给 filter 赋值,而是定义了一套“变量占位符”。其生成的 CSS 伪代码逻辑如下:
/* Tailwind 的底层逻辑 */
:root {
--tw-blur: ;
--tw-brightness: ;
}
.blur-sm { --tw-blur: blur(4px); }
.brightness-50 { --tw-brightness: brightness(0.5); }
/* 核心技巧:所有的工具类最终都指向这同一个 filter 定义 */
.filter-logic-base {
filter: var(--tw-blur) var(--tw-brightness);
}
任意值(Arbitrary Values)
核心要点总结
| 场景 | 语法示例 | 说明 |
|---|---|---|
| 特定颜色 | bg-[#hex] | 直接使用十六进制颜色。 |
| 复杂布局 | grid-cols-[...] | 处理 minmax()、fr 等复杂单位。 |
| 数学计算 | h-[calc(...)] | 在类名中直接写 CSS 计算公式。 |
| CSS 变量 | [--var:value] | 快速定义局部变量,无需写 <style> 标签。 |
即时编译(Just-in-Time, JIT)
Tailwind CSS 并不是你可能习惯的那种大型静态样式表——它是当你编译 CSS 时,根据你实际使用到的类名来动态生成所需的 CSS。 在找到所有潜在的类名后,Tailwind 会为每一个类生成对应的 CSS,并将其全部编译进一个只包含你真正需要的样式的样式表中。
由于 CSS 是基于类名生成的,所以 Tailwind 能够识别像 bg-[#316ff6] 这样带有任意值的类,并生成必要的 CSS,即使该值并不在你预设的主题中。
为什么它能识别 bg-[#316ff6]?
因为 Tailwind 并不是在查找一个“预先定义好的颜色表”,而是在运行一个正则表达式扫描器。
- 扫描:它看到你的代码里有
bg-[#316ff6]。 - 解析:它识别出
bg-前缀和方括号中的#316ff6。 - 生成:它在内存中实时生成一段 CSS:
.bg-[#316ff6] { background-color: #316ff6; }。 - 输出:最后这段代码被写入你的最终 CSS 文件。
⚠️ 注意事项:动态类名的坑
正如文中所说,Tailwind 是通过“扫描源码”来工作的。这意味着它不会执行你的代码。
- 错误做法:
className={"text-" + errorColor}(扫描器找不到完整的字符串,无法生成 CSS)。 - 正确做法:
className={errorColor === 'red' ? 'text-red-500' : 'text-gray-500'}(扫描器能看到完整的类名字符串)。
这段文字介绍了 Tailwind 中非常强大的“父子级联动样式”功能:Group 状态,以及更高级的任意变体(Arbitrary Variants) 。
Group
Tailwind 还支持像 group-hover 这样的特性,让你可以在某个特定的父元素被悬停(hover)时,为其中的子元素设置样式:
HTML
<a href="#" class="group rounded-lg p-8">
<span class="group-hover:underline">阅读更多…</span>
</a>
简化后的 CSS 逻辑如下:
CSS
@media (hover: hover) {
a:hover span {
text-decoration-line: underline;
}
}
这种 group-* 语法也适用于其他变体,例如 group-focus(父元素获得焦点)、group-active(父元素被按下)等等。
对于极其复杂的场景(特别是当你需要为不受你控制的 HTML 编写样式时),Tailwind 支持任意变体,这让你能够直接在类名中编写任何你想要的 CSS 选择器:
核心要点总结
1. Group 状态 (The group Power)
- 原理:在父元素标记
group类,然后在子元素使用group-hover:等前缀。 - 优势:不再局限于“悬停子元素本身才变色”,而是可以实现“悬停整个卡片时,内部的某个按钮或文字发生变化”。
- 常见组合:
group-hover、group-focus、group-last(父元素是最后一个子元素时)。
2. 任意变体 (Arbitrary Variants)
这是 Tailwind 灵活性的顶峰。它的语法通常使用方括号 [],允许你编写复杂的 CSS 选择器。
例如:
[&_p]:mt-4:选中当前元素下所有的<p>标签并给它们设置margin-top。[:nth-child(3)]:underline:选中第三个子元素并加下划线。
内联样式的使用
-
真正的动态数据:如果你无法预知颜色(例如用户在后台自定义的品牌色),由于 Tailwind 在编译时无法生成未知的类名,必须使用
style属性。 -
可读性优先:当方括号内的内容(如复杂的
calc或grid)超过 50 个字符时,写在style里会让 HTML 结构更整洁。 -
桥接模式(CSS 变量) :这是最高级的用法。通过
style定义变量,再用 Tailwind 处理状态(如hover:)。- 优点:内联样式很难直接处理
hover状态,但通过变量转换后,你可以轻松写出hover:bg-(--custom-color)。
- 优点:内联样式很难直接处理