Tailwind 到底是设计师喜欢,还是开发者在硬撑?

我们最近刚把一个后台系统从 element-plus 切成了完全自研组件,CSS 层统一用 Tailwind。全员同意设计稿一致性提升了,但代码里怨言开始冒出来。

这篇文章不讲原理,直接上代码对比和团队真实使用反馈,看看是谁在享受,谁在撑着。


1.组件内样式迁移

原先写法(BEM + scoped):

html 复制代码
<template>
  <div class="card">
    <h2 class="card__title">用户概览</h2>
    <p class="card__desc">共计 1280 位</p>
  </div>
</template>

<style scoped>
.card {
  padding: 16px;
  background-color: #fff;
  border-radius: 8px;
}
.card__title {
  font-size: 16px;
  font-weight: bold;
}
.card__desc {
  color: #999;
  font-size: 14px;
}
</style>

Tailwind 重写:

html 复制代码
<template>
  <div class="p-4 bg-white rounded-lg">
    <h2 class="text-base font-bold">用户概览</h2>
    <p class="text-sm text-gray-500">共计 1280 位</p>
  </div>
</template>

优点:

  • 组件直接可读,不依赖 class 定义
  • 样式即结构,调样式时不用来回翻

缺点:

  • 设计稿变了?全组件搜索 text-sm 改成 text-base
  • 无法抽象:多个地方复用 .text-label 变成复制粘贴

2.复杂交互样式

纯 CSS(原写法)

html 复制代码
<template>
  <button class="btn">提交</button>
</template>

<style scoped>
.btn {
  background-color: #409eff;
  color: #fff;
  padding: 8px 16px;
  border-radius: 4px;
}
.btn:hover {
  background-color: #66b1ff;
}
.btn:active {
  background-color: #337ecc;
}
</style>

Tailwind 写法

html 复制代码
<button
  class="bg-blue-500 hover:bg-blue-400 active:bg-blue-700 text-white py-2 px-4 rounded">
  提交
</button>

问题来了:

  • ✅ 简单 hover/active 很方便
  • ❌ 多态样式(如 disabled + dark mode + hover 同时组合)就很难读:
html 复制代码
<button
  class="bg-blue-500 text-white disabled:bg-gray-300 dark:bg-slate-600 dark:hover:bg-slate-700 hover:bg-blue-600 transition-all">
>
  提交
</button>

调试时需要反复阅读 class 字符串,不能直接 Cmd+Click 查看样式来源。


3.统一样式封装,复用方案混乱

原写法:统一样式变量 + class

scss 复制代码
$border-color: #eee;

.panel {
  border: 1px solid $border-color;
  border-radius: 8px;
}

Tailwind 使用中经常出现的写法:

html 复制代码
<div class="border border-gray-200 rounded-md" />

问题来了:

设计稿调整了主色调或边框粗细,如何批量更新?

BEM 模式下你只需要改一个变量,Tailwind 下必须靠 @apply 或者手动替换所有 .border-gray-200

于是我们项目里又写了一堆"语义类"去封装 Tailwind:

scss 复制代码
/* 自定义 utilities */
@layer components {
  .app-border {
    @apply border border-gray-200;
  }
  .app-card {
    @apply p-4 rounded-lg shadow-sm bg-white;
  }
}

最后导致的问题是:我们重新"造了个 BEM",只不过这次是基于 Tailwind 的 apply 写法。


🧪 实测维护成本:100+组件、多人协作时的问题

我们项目有 110 个组件,4 人开发,统一用 Tailwind,协作两个月后出现了这些反馈:

  • 👨‍💻 A 开发:写得很快,能复制设计稿的 class 直接粘贴
  • 🧠 B 维护:改样式全靠人肉找 .text-sm.p-4,没有结构命名层
  • 🤯 C 重构:统一调整圆角半径?所有 .rounded-md 都要搜出来替换

所以我们内部的结论是:

Tailwind 写得爽,维护靠人背。它适合"一次性强视觉还原",不适合"结构长期型组件库"。


🔧 我们后来的解决方案:Tailwind + token 化抽象

我们仍然使用 Tailwind 作为底层 utilities,但同时强制使用语义类抽象,例如:

scss 复制代码
@layer components {
  .text-label {
    @apply text-sm text-gray-500;
  }

  .btn-primary {
    @apply bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded;
  }

  .card-container {
    @apply p-4 bg-white rounded-lg shadow;
  }
}

模板中统一使用:

html 复制代码
<h2 class="text-label">标题</h2>
<button class="btn-primary">提交</button>
<div class="card-container">内容</div>

这种方式保留了 Tailwind 的构建优势(无 tree-shaking 问题),但代码结构有命名可依,后期批量维护不再靠搜索。


📌 最终思考

Tailwind 是给设计还原速度而生的,不是给可维护性设计的。 设计师爱是因为它像原子操作; 开发者撑是因为它把样式从结构抽象变成了"字串组合游戏"。

如果你的团队更在意开发效率,样式一次性使用,那 Tailwind 非常合适。 如果你的组件系统是要长寿、要维护、要被多人重构的------你最好在 Tailwind 之上再造一层自己的语义层,或者别用。

分享完毕,谢谢大家🙂

📌 你可以继续看我的系列文章

相关推荐
未来之窗软件服务1 分钟前
jquery 赋值时不触发change事件解决——仙盟创梦IDE
前端·javascript·jquery·仙盟创梦ide·东方仙盟
Nicander5 分钟前
如何实现css变量中vscode编辑器中的类型提示
css
AnyaPapa6 分钟前
【解决方案】Vue 常见问题大全
前端·javascript·vue.js
三小河16 分钟前
在ts 中 对于常见的内置工具类型、类型操作符和关键字简单解释
前端
૮・ﻌ・17 分钟前
前端HTML学习笔记
前端·笔记·html·黑马程序员
用户276920244534621 分钟前
Cesium 三维地球开发:一站式弹窗、坐标转换与可视化扩展(持续进化中)
前端
阿星AI工作室32 分钟前
n8n教程:5分钟部署+自动生AI日报并写入飞书多维表格
前端·人工智能·后端
浩宇软件开发44 分钟前
JavaScript 数组常用方法 find, findIndex, filter, map, flatMap, some
前端·javascript·vue.js
一涯1 小时前
关于富文本\n处理
前端
鸿蒙小林1 小时前
《仿盒马》app开发技术分享-- 回收订单状态修改与展示(44)
前端