在 Tailwind 项目 PlatoBlockchain 数据智能中使用 CSS 级联层管理自定义样式。 垂直搜索。 哎。

在 Tailwind 项目中使用 CSS 级联层管理自定义样式

如果实用程序类只做一件事,那么您很可能不希望它被来自其他地方的任何样式覆盖。 一种方法是使用 !important 100% 确定样式将被应用,无论具体冲突如何。

Tailwind 配置文件有一个 !important 将自动添加的选项 !important 到每个实用程序类。 使用没有问题 !important 这种方式,但现在有更好的方法来处理特异性。 使用 CSS 级联层 我们可以避免使用粗暴的方法 !important.

级联层允许我们将样式分组为“层”。 层的优先级总是胜过选择器的特殊性。 特异性只在每一层内很重要。 建立合理的层顺序有助于避免样式冲突和特殊性战争。 这就是使 CSS Cascade Layers 成为出色工具的原因 管理自定义样式以及来自第三方框架的样式,比如顺风。

顺风源 .css 文件通常以这样的开头:

@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind variants;

我们来看看吧 官方 Tailwind 文档 关于指令:

指令是自定义的特定于 Tailwind 的规则,您可以在 CSS 中使用,为 Tailwind CSS 项目提供特殊功能。 使用 @tailwind 插入 Tailwind 的指令 base, components, utilitiesvariants 样式到你的 CSS 中。

在生成的输出 CSS 文件中,Tailwind 的 CSS 重置 - 称为 飞行前 — 首先作为基本样式的一部分包含在内。 其余的 base 由 Tailwind 工作所需的 CSS 变量组成。 components 是您添加自己的自定义类的地方。 您在标记中使用的任何实用程序类都将出现在下一个。 变体是悬停和焦点状态以及响应式样式等样式,它们将出现在生成的 CSS 文件中的最后。

顺风 @layer 指示

令人困惑的是,Tailwind 有自己的 @layer 句法。 本文是关于 CSS 标准的,但让我们快速了解一下 Tailwind 版本(它会被编译掉并且不会出现在输出 CSS 中)。 顺风 @layer 指令是一种将您自己的额外样式注入输出 CSS 文件的指定部分的方法。

例如,要将您自己的样式附加到 base 样式,您将执行以下操作:

@layer base {
  h1 {
    font-size: 30px;
  }
}

components layer 默认是空的——它只是一个放置你自己的类的地方。 如果您以 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 甚至会显示您定义的任何层。

在 Tailwind 项目中使用 CSS 级联层管理自定义样式

您可以拥有任意数量的图层 - 并根据需要命名它们 - 但在此示例中,我所有的自定义样式都在一个图层中(my-custom-styles)。 第一行建立层顺序:

@layer tailwind-base, my-custom-styles, tailwind-utilities;

这需要预先提供。 确保在使用的任何其他代码之前包含此行 @layer. 列表中的第一层将是 最少 功能强大,列表中的最后一层将是 最先进的 强大的。 这意味着 tailwind-base最不强大 层和其中的任何代码都将被所有后续层覆盖。 这也意味着 tailwind-utilities 将永远胜过任何其他风格- 无论来源顺序或特异性如何. (实用程序和变体 可以 进入单独的层,但 Tailwind 的维护者将确保变体始终胜过实用程序,只要您在实用程序指令下方包含变体。)

不在图层中的任何内容都将覆盖图层中的任何内容(一个例外是使用 !important)。 所以,你也可以选择离开 utilitiesvariants 在任何层之外:

@layer tailwind-base, tailwind-components, my-custom-styles;

@layer tailwind-base {
  @tailwind base;
}

@layer tailwind-components {
  @tailwind components;
}

@tailwind utilities;
@tailwind variants;

这实际上给我们带来了什么? 很多时候高级 CSS 选择器会派上用场。 让我们创建一个版本 :focus-within 只响应键盘焦点而不是使用鼠标点击 :has 选择器 (登陆 Chrome 105)。 这将在其任何子元素获得焦点时设置父元素的样式。 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-colorblue 到别的东西。 假设我们正在使用的元素同时具有 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 使用来得到我们想要的。

时间戳记:

更多来自 CSS技巧