Tailwind v4 升级后边框全变黑了?是 currentColor 在作怪
项目从 Tailwind v3 升级到 v4 之后,UI 走查时发现卡片边框、骨架屏外框、输入框描边全都变成了粗重的近黑色。第一反应是暗色模式配置出了问题,但切换到亮色模式——还是黑的。TypeScript 报错?零个。构建警告?零条。打开 DevTools,class 列表里 border 赫然在列,看起来完全正常。
折腾了一会儿才意识到:这是 v4 的一个静默 breaking change,影响所有写了裸 border、divide-y、ring 而没有加颜色类的地方。
现象
- 升级
tailwindcss到^4.x后,凡是只写了border(没有配套的border-<color>)的元素,边框都渲染成近黑色。 - 亮色模式和暗色模式均复现——说明边框颜色跟主题无关,而是跟文字颜色绑定了。
divide-x/divide-y画出来的分割线同样受影响,变成一条黑线。ring-2的光圈也从预期的柔和蓝变成了黑色轮廓。- 构建全绿,无任何错误或警告提示。
根因
Tailwind v3 在 Preflight(全局样式重置)里有一条规则,给所有元素设置了默认边框颜色 gray-200:
/* Tailwind v3 Preflight */
*, ::before, ::after {
border-color: theme(colors.gray.200);
}所以 v3 里写裸 border 就能得到一条浅灰边框——这是很多人习以为常的"隐式默认"。
Tailwind v4 把这条规则彻底删掉了。 裸 border 退化回 CSS 的初始行为:边框颜色跟 currentColor 走,也就是当前元素的文字颜色。在大多数设计系统里,默认文字色是近黑的 foreground,于是边框就变成了黑色。
这个变化写在 v4 升级指南的"Default border color"章节,但属于无错误的静默破坏——没有 lint 规则能直接拦住它,只有视觉走查才能发现。
在 Tailwind v4 里,border、border-2、border-t、divide-y、ring-2 这类只有宽度、没有颜色的 utility,边框颜色默认是 currentColor(元素文字色),而不是 v3 时代的 gray-200。升级后不改代码,UI 里所有"忘记加颜色类"的边框都会悄悄变黑,零报错。
正解
最直接的修法:每一个 border/ring/divide 宽度类,都要搭配一个明确的颜色类。
- <div className="rounded-xl border p-4">
+ <div className="rounded-xl border border-border p-4">
- <ul className="divide-y">
+ <ul className="divide-y divide-border">
- <button className="ring-2 focus:ring-2">
+ <button className="ring-2 ring-border focus:ring-2 focus:ring-ring">更深层的修法是不要手撸带边框的容器壳——如果项目里已经有封装好的 Card 组件,它的 variant 里应该已经编码了 border border-border,直接用组件就不会踩这个坑。手撸 rounded + border + p-4 本质上是在外面又复制了一个 Card 的壳,复制出来的壳最容易漏掉颜色类。
如果你想一次性修掉整个代码库,也可以在全局 CSS 里恢复 v3 的行为作为兜底:
@layer base {
*, ::before, ::after {
border-color: var(--color-border);
}
}不过更推荐在组件代码里逐一加颜色类——全局覆盖会掩盖掉"忘加颜色"的坏习惯,后续维护时更容易出现预期外的颜色覆盖。
养成习惯:写 border 的同时写 border-border,写 divide-y 的同时写 divide-border,写 ring-2 的同时写 ring-border。如果项目有设计系统组件,优先用组件而不是手撸边框壳,让组件的 variant 来保证颜色正确。
快速排查
用 grep 把代码库里所有裸 border 扫出来:
grep -rn '\bborder\b' src | grep -v 'border-'输出的每一行都是潜在的 v4 变黑候选,逐一补上颜色类。
一句话外卖
Tailwind v4 起,
border不再送你一条灰边——不写颜色类,边框跟文字色走,一律变黑;升级后第一件事是全局 grep 裸 border 并补色。