根本解法是用prefix: 'tw-'前缀隔离类名,配合@layer components收编自定义组件样式、禁用preflight,并避免滥用!important;因类名冲突本质是字符串重复而非加载顺序问题,前缀从源头杜绝碰撞,而权重和顺序控制需协同生效。

根本不是 Tailwind “没生效”,而是原生 CSS 和 Tailwind 工具类在浏览器里打了个平手——text-blue-500 和 .btn 都是特异性 0,1,0,谁后加载,谁赢。
为什么原生 CSS 会“赢过” Tailwind?
关键不在“谁更高级”,而在加载顺序和选择器权重是否真正拉开差距:
- 你写的
.header { color: #374151; }和 Tailwind 的text-gray-700权重一样,如果.header的 CSS 文件在tailwind.css之后引入,它就覆盖了 - Vue/React 组件里用了
<style scoped>,但 Tailwind 是全局注入的,scoped 样式天然带属性选择器(如.header[data-v-abc123]),权重反而更高(0,1,1,0) - 原生 CSS 里用了 ID 或组合选择器(如
#app .card-title),权重直接跳到0,1,1,0或更高,Tailwind 单类根本压不住
怎么让 Tailwind 在冲突中稳住?
别靠“写得晚”,靠明确控制层级和作用域:
- 在
tailwind.config.js里开prefix: 'tw-',把所有工具类变成tw-text-blue-500,和你的.btn、.card彻底隔开 - 用
@layer components把覆盖逻辑收进 Tailwind 体系:比如写@layer components { .btn-primary { @apply bg-blue-600 text-white; } },它会排在@tailwind utilities前面,权重相同但顺序可控 - 禁用 Preflight(
corePlugins.preflight: false)——很多“覆盖感”其实来自 Tailwind 默认重置了h1、p、img的 margin/padding,关掉后原生语义样式才真正露出来
为什么 !important 是条死胡同?
它确实能压倒一切,但代价是你再也分不清哪条样式生效了:
立即学习“前端免费学习笔记(深入)”;
- Element Plus 的
.el-button.is-disabled本身就有!important,你加了也白加 - DevTools 的 Styles 面板里全是划掉线,Computed 面板看不出真实来源,调试成本翻倍
- Tailwind 官方明确说
important: true只用于极端集成场景,不是日常解法
真正容易被忽略的是:Tailwind 工具类之间也有顺序依赖——rounded-md 和 rounded-full 不是“后写的生效”,而是看它们在最终 CSS 文件里的定义位置;一旦构建缓存没清、Vite HMR 没刷新、或者 @tailwind 指令被挪动,这个顺序就乱了,连 class="rounded-full rounded-md" 都可能失效。


















