发布于 2026-01-06 1 阅读
0

Tailwind CSS 可能不适合您

Tailwind CSS 可能不适合您

免责声明:本文是我对Tailwind CSS 的另一种解读:它只会增加复杂性,却毫无作用。我尊重原作者的观点,但我认为有更好的方式来批评 Tailwind CSS。以下是我的观点。

如果你从事前端开发,你可能听说过 Tailwind CSS,它是一个类似 Bootstrap 的 CSS 框架。然而,与 Bootstrap 不同的是,Tailwind 采用了不同的方法——它几乎完全由“实用类”构成。

它可能并不适合所有人。

在开始之前,让我先解释一下什么是实用类。假设你有很多组件,其中很多都需要 CSS 声明display: flex;。与其在 CSS 中一遍又一遍地编写相同的声明,不如创建一个名为 `utility class` 的类flex

.flex {
  display: flex;
}
Enter fullscreen mode Exit fullscreen mode

然后,在每个需要进行弹性变形的组件中,添加该类flex

这并非坏事。我自己也经常编写和使用工具类,尤其是在不使用 CSS-in-JS 解决方案或 Sass/SCSS 等预处理器的情况下编写 CSS 时。

Tailwind 将这个概念发挥到了极致,其理念是几乎不需要编写 CSS,只需根据需要应用不同的样式,向 HTML 添加不同的类即可。

这是一个有趣的抉择,因为……

这就是对内联样式的拥抱

在样式表出现之前,HTML 中有一些元素,例如 `<style>`<font>和` <center><style>`,可以直接在标记中应用一些基本样式,很像styleCSS 的 `style` 属性。虽然现在内联样式仍然存在,但我们知道最好不要再使用它们,因为我们现在有了样式表,它允许我们“分离职责”:HTML 用于内容和结构,CSS 用于表现形式。

然而,Tailwind 并没有遵循这种理念,而是回归了 90 年代的做法,将内容和表现形式混合在同一个文件中。那么,为什么不直接使用内联样式呢?编写 `<style>`<div class="flex">foo</div>和编写 `<style>` 的效果完全相同。其实,正如 Tailwind 文档中所述<div style="display: flex;">foo</div>,这其中有几个原因。值得注意的是,内联样式不支持媒体查询或伪类选择器(例如 `<style>` 或 `<style>`)因此无法实现响应式或动态样式。仅凭这一点,除非你假装移动设备不存在,否则使用内联样式构建整个应用程序或网站几乎是不可能的。如果这还不够充分,Tailwind 还提出了一个强有力的论点,即“在限制条件下进行设计”::hover:focus

使用内联样式时,每个值都是一个神奇的数字。而使用实用程序,您可以从预定义的设计系统中选择样式,这使得构建视觉上一致的用户界面变得更加容易。

事实上,Tailwind 的主题配置是其最大的优势之一。它避免了样式表中出现69 种不同的字体大小以及一些明明应该相同却又如此相似的背景颜色(例如 `<span>`#ffe42e和`<span> #ffe322`)。它还能帮助开发者更快地进行设计,并更有信心避免引入视觉上的不一致。

尽管 Tailwind 对内联样式做了很多改进,但它仍然秉承了内联样式的理念,认为将样式表述与内容混合在一起完全没问题,甚至可以说是可取的。因此,一些反对使用内联样式的理由,同样也适用于反对使用 Tailwind。我知道,仅仅为了解释为什么 Tailwind 可能不适合你而重复其他用户对内联样式的批评似乎有点偷懒,但我们还是来谈谈这个吧:

是湿的,不是干的

当您想要对网站样式进行大幅更改时,如果您使用了实用类,则需要逐一检查这些实用类的每次使用情况——也就是每个组件——并直观地确定哪些部分需要更新。例如,假设您公司的主色调是蓝色。您的网站上会有很多蓝色元素,它们使用诸如 `color`text-blue-700或 `color` 之类的类进行标记bg-blue-500,这些类代表不同的蓝色色调。这在公司决定进行品牌重塑之前都没问题,但现在网站上的所有按钮——仅限按钮——都需要变成红色。

如果你使用的是传统的 CSS,你可能会有一个名为 `<class>` 的类button。你只需要在 CSS 中找到这个类,然后修改一行代码:`<class=" background-color: red;red">`。任何使用该类定义的元素现在都会变成红色。

相反,使用 Tailwind 时,你必须逐个组件进行手动修改bg-blue-500。1000bg-red-500次修改就意味着 1000 次引入 bug 的机会。这几乎就是 DRY 原则存在意义的教科书式例证。

也就是说,除非你把之前因为button在 HTML 中用一堆工具类替换而丢失的抽象层找回来。以我的经验来看,如果把所有曾经是“CSS 组件”(比如类button)的东西都变成“模板组件”(一个包含标记和样式的可重用文件),Tailwind 的效果会更好。仔细想想,这很有道理,而且最终还能减少更多重复代码:不仅是 Tailwind 类现在放在一个文件里而不是 1000 个,还有组件的任何属性(比如 ARIA)或子元素(比如 `<div>` button__icon)。事实证明,代码的 DRY 原则取决于你自己,而不是 Tailwind!

以上假设你正在使用某种组件库(例如 React、Vue、Svelte 等)或支持局部视图的模板语言(例如 Twig、Blade、PHP 等)。如果你没有使用这些库,或者觉得为一个简单的按钮创建组件或局部视图很麻烦,那也完全没问题。你无需更改抽象模型,仍然可以使用 CSS 本身作为“组件层”。Tailwind 的一个@apply特性正能派上用场:你可以保留你的button类,但不再使用 `<class>` background-color: red;,而是使用 `<class>` @apply bg-red-500;。这样,你仍然可以使用主题配置,而不是硬编码的(魔法)值。这类似于使用预处理器或 CSS 变量,但使用的是 Tailwind API。

传统上,HTML关注的是结构,而不是样式。

人们在开发中经常谈到关注点分离。CSS Modules(尤其是.vue文件)在很大程度上消除了将网站每个构建块的结构、行为和样式分别放在不同文件夹中的观念,但关注点分离仍然有其价值。也就是说,代码的每个部分都应该是“松耦合且高内聚”的。

换句话说,你的 HTML(结构语法)不应该包含关于样式的信息;它应该只包含关于页面结构的信息。事实上,CSS 发明的最终目的,或者说整个 CSS 项目的全部意义……正是为了将内容与表现形式分离。

然而,Tailwind 却采用了内联样式,这与分离关注点的理念背道而驰。这是为什么呢?Tailwind 的作者 Adam Wathan 曾撰文指出,分离关注点其实是一个“稻草人谬论”,我们应该从“依赖方向”的角度来思考这个问题。这篇文章篇幅较长,但值得一读,它能帮助我们理解 Tailwind 的设计理念。

事实证明,Tailwind 和大多数 CSS 框架一样,面向的是那些喜欢编写依赖于 CSS 的 HTML 代码,而不是依赖于 HTML 的 CSS 代码的开发者。Adam 指出,这两种方法都完全有效,关键在于“在特定情况下,哪种方法对你来说更重要”。Tailwind 采用了第一种方法,并尽可能地将其发挥到了极致。因此,开发者可以直接在 HTML 中构建自定义 UI,因为 CSS 提供了所有必要的构建模块。

我们编写代码时,要面向两个受众:第一个是计算机本身,它并不关心代码的外观,只要代码能够运行即可;第二个是我们的程序员同事。他们越容易快速识别程序的各个部分及其相互关系,就能越快地修复错误、添加功能,并为组织创造价值。Tailwind 不仅让构建用户界面变得简单,无需切换上下文,还能让用户一眼了解每个元素的外观,因为样式都集中在同一个文件中。

用实用类名取代“语义化”类名的另一面是,HTML 代码片段所代表的内容变得不那么清晰。幸运的是,这个问题很容易解决,只需使用命名良好的组件,或者添加注释,甚至添加只用于描述元素的类(显然,要放在第一个,以免淹没在众多实用类中)。

一开始很难读懂。

如果你看到一些使用了 Tailwind 的 HTML 代码,你可能会觉得这些代码看起来“杂乱”甚至“难看”。的确如此,但有人说你会慢慢习惯的。

真正的难点在于,即使你精通 CSS,也必须先学习所有这些类才能高效使用它。Tailwind 框架充斥着语义晦涩的缩写,例如 ` wfor`width和 ` hfor` height。该框架力求在简洁性和表达力之间取得平衡,但初次使用时确实会让人感到晦涩难懂。

以下是亚历山大·霍夫汉尼斯扬举的一个例子。

这是 Tailwind 代码:

<div class="w-4 h-4 rounded text-white bg-black py-1 px-2 m-1 text-sm md:w-8 md:h-8 md:rounded-md md:text-base lg:w-12 lg:h-12 lg:rounded-lg lg:text-lg">
  Yikes.
</div>
Enter fullscreen mode Exit fullscreen mode

可以表示为:

<style>
  .thing {
    width: 1rem;
    height: 1rem;
    color: white;
    background-color: black;
    padding: 0.25rem 0.5rem;
    margin: 0.25rem;
    border-radius: 0.25rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
  }

  @media screen and (min-width: 768px) {
    .thing {
      width: 2rem;
      height: 2rem;
      border-radius: 0.375rem;
      font-size: 1rem;
      line-height: 1.5rem;
    }
  }

  @media screen and (min-width: 1024px) {
    .thing {
      width: 3rem;
      height: 3rem;
      border-radius: 0.5rem;
      font-size: 1.125rem;
      line-height: 1.75rem;
    }
  }
</style>

<div class="thing">Yikes.</div>
Enter fullscreen mode Exit fullscreen mode

如您所见,每种方法各有优缺点。第二个示例更具表现力(尤其如果您不了解 Tailwind),但代码量更大,而且样式与它们所影响的元素是分离的。另一方面,Tailwind 代码简洁明了,您无需打开其他文件即可理解其样式。您可能会觉得它晦涩难懂,但只需使用几天,您就能轻松理解。

值得注意的是,Tailwind 类是水平排列的,而 CSS 是垂直编写的。文本越宽,读者的视线就越难跳转到下一行,也就越难在一大段水平文本中找到你想要查找的特定单词。这也是 Tailwind 类简洁的原因之一(除了打字速度和文件大小之外)。请注意,有很多方法可以避免行过长(例如在 IDE 中启用自动换行、添加换行符、@apply选择性地使用 CSS 等),但这仍然是一个需要注意的潜在问题。

这完全取决于个人喜好。Tailwind 或许适合你,或许不适合,但如果不实际尝试一下,很难知道它是否适合你。

你会失去标准 CSS 中内置的许多功能。

……如果你坚持不使用任何自定义 CSS 的话。但实际上,大多数 Tailwind 项目都包含一些自定义 CSS,这完全没问题——Tailwind 本身就是一个 PostCSS 插件,这意味着它是在 CSS 源文件上运行的,而不是取代 CSS 源文件。

p因此,如果您想要一些特定的样式规则,例如在类内的标签之间添加一些边距description,则需要编写自定义 CSS,但这并不妨碍您使用@apply

.description p + p {
  @apply mt-4;
}
Enter fullscreen mode Exit fullscreen mode

请注意,还有许多插件(包括一些官方插件,例如TypographyForms)可以扩展 Tailwind 的核心功能。

它解决了一个你可能没有遇到过的问题。

我们每个人都不一样。我们从事不同的项目,采用不同的方法论,使用不同的工具。没有哪一款工具能够解决所有人面临的问题。它所能做的,就是服务于那些正在经历它所针对的特定问题的用户,并提供完善的文档和其他资源,帮助用户了解如何利用它来简化工作或生活。

Tailwind 正是如此。但它并不适合所有人。如果你读过 Adam Wathan 的《CSS 实用类与“关注点分离”》一文,却仍然无法理解,那么我很高兴地告诉你,Tailwind 可能并不适合你。如果你最喜欢编写自定义 CSS,或者你需要对同一段 HTML 应用不同的样式表来彻底改变其外观,那么 Tailwind 也不适合你。没关系!继续使用你喜欢的工具,创造更多精彩的作品吧。

世上没有完美的东西。

最终肯定会有其他技术出现,解决 Tailwind 的一些问题,但也可能带来我们无法想象的新问题。也许它会成为一项核心 Web 技术,谁知道呢。但与此同时,如果您或您的团队决定使用 Tailwind,它将提供卓越的开发体验,拥有我见过的开源项目中最好的文档之一,您的 CSS 文件将比以往任何时候都更加精简,一段时间后,您或许会惊叹自己以前是如何用其他方式编写 CSS 的。

文章来源:https://dev.to/benface/tailwind-css-might-not-be-for-you-jk0