如果一个实用类只做一件事,你很可能不希望它被来自其他地方的任何样式所覆盖。一种方法是使用!important ,以100%确定该样式将被应用,而不考虑特殊性冲突。
Tailwind配置文件中有一个!important 选项,它将自动把!important 添加到每个实用类中。这样使用!important 并没有错,但是现在有更好的方法来处理特殊性。使用CSS级联层,我们可以避免使用!important 的强硬做法。
级联层允许我们将样式分组为 "层"。一个层的优先级总是胜过一个选择器的具体性。特异性只在每个层内重要。建立一个合理的层级顺序有助于避免样式冲突和特殊性的争斗。这就是为什么CSS层叠层是管理自定义样式和第三方框架(如Tailwind)样式的伟大工具。
一个Tailwind源文件.css ,通常是这样开始的:
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind variants;
让我们来看看关于指令的Tailwind官方文档:
指令是定制的针对Tailwind的at-rules,你可以在你的CSS中使用,为Tailwind CSS项目提供特殊功能。使用
@tailwind指令,将Tailwind的base、components、utilities和variants样式插入你的CSS中。
在被构建的输出CSS文件中,Tailwind的CSS重置--被称为Preflight--首先作为基本样式的一部分被包含。base 的其余部分由尾风工作所需的CSS变量组成。components 是一个让你添加自己的自定义类的地方。你在你的标记中所使用的任何实用类将会出现在接下来。变量是用于诸如悬停和焦点状态以及响应式的样式,它们将在生成的CSS文件中最后出现。
Tailwind@layer 指令
令人困惑的是,Tailwind有自己的@layer 语法。这篇文章是关于CSS标准的,但是让我们快速看一下Tailwind的版本(它被编译掉了,并没有最终出现在输出的CSS中)。Tailwind@layer 指令是一种将你自己的额外样式注入到输出CSS文件的指定部分的方法。
例如,要将你自己的样式附加到base 样式中,你可以这样做:
@layer base {
h1 {
font-size: 30px;
}
}
components 层默认是空的--它只是一个放置你自己的类的地方。如果你按照Tailwind的方式做事,你可能会使用 @apply(虽然Tailwind的创建者最近建议不要这样做),但是你也可以用常规的方式来写类:
@layer components {
.btn-blue {
background-color: blue;
color: white;
}
}
CSS标准要强大得多。让我们回到这个话题上来...
使用CSS标准@layer
下面是我们如何重写这个,以使用CSS标准@layer:
@layer tailwind-base, my-custom-styles, tailwind-utilities;
@layer tailwind-base {
@tailwind base;
}
@layer tailwind-utilities {
@tailwind utilities;
@tailwind variants;
}
与Tailwind指令不同,这些指令不会被编译掉。它们会被浏览器理解。事实上,Edge、Chrome、Safari和Firefox的DevTools甚至会显示你所定义的任何层。

你可以有任意多的图层--并且随心所欲地命名它们--但是在这个例子中,我所有的自定义样式都在一个单一的图层中(my-custom-styles )。第一行确定了图层的顺序。
@layer tailwind-base, my-custom-styles, tailwind-utilities;
这需要在前面提供。请确保在任何其他使用@layer 的代码之前包含这一行。列表中的第一个层将是最不强大的,而列表中的最后一个层将是最强大的。这意味着tailwind-base 是最不强大的层,其中的任何代码都会被后面所有的层所覆盖。这也意味着tailwind-utilities 将永远胜过任何其他的风格--不管来源顺序或特殊性如何。(公用程序和变体可以放在不同的层中,但是Tailwind的维护者会确保变体总是优先于公用程序,只要你在公用程序指令下面包含变体。)
任何不在一个层中的东西都会覆盖在一个层中的东西(唯一的例外是使用!important 的样式)。所以,你也可以选择把utilities 和variants 放在任何层之外:
@layer tailwind-base, tailwind-components, my-custom-styles;
@layer tailwind-base {
@tailwind base;
}
@layer tailwind-components {
@tailwind components;
}
@tailwind utilities;
@tailwind variants;
这实际上给我们带来了什么呢? 有很多时候,高级的CSS选择器是非常有用的。让我们使用:has 选择器(在Chrome 105中登陆)创建一个只对键盘焦点而不是鼠标点击做出反应的:focus-within 的版本。这将在一个父元素的任何一个子元素收到焦点时,对其进行样式设计。Tailwind 3.1引入了自定义变体--例如:<div class="[&:has(:focus-visible)]:outline-red-600"> --但有时直接写CSS会更容易。
@layer tailwind-base, my-custom-styles;
@layer tailwind-base {
@tailwind base;
}
@tailwind utilities;
@layer my-custom-styles {
.radio-container {
padding: 4px 24px;
border: solid 2px rgb(230, 230, 230);
}
.radio-container:has(:focus-visible) {
outline: solid 2px blue;
}
}
比方说,在一个实例中,我们想把outline-color 从blue 覆盖到其他东西。假设我们正在处理的元素既有Tailwind的.outline-red-600 类,也有我们自己的.radio-container:has(:focus-visible) 类。
<div class="outline-red-600 radio-container"> ... </div>
哪一个outline-color 会赢呢?
通常情况下,.radio-container:has(:focus-visible) 的较高特异性将意味着Tailwind类没有影响--即使它在源顺序中较低。但是,与依赖源顺序的Tailwind@layer 指令不同,CSS标准@layer 凌驾于特定性之上。
因此,我们可以在我们自己的自定义样式中使用复杂的选择器,但当我们需要的时候,仍然可以用Tailwind的实用类来覆盖它们--而不必借助于强硬的!important 来获得我们想要的东西。