写了十一年CSS我才敢承认:Tailwind正在偷偷废掉你的基本功
摘要:原子化框架提升了效率,却可能让开发者失去对CSS底层机制的理解。本文分析这种能力置换的代价,并提供自测与补课方法。
十一年前我开始写CSS的时候,还没有人把“原子化”这个词挂在嘴边。那时候我们争论的是浮动该不该用来布局,是IE6的盒模型到底怎么绕。后来Flexbox来了,Grid来了,预处理器来了又走,CSS Modules和CSS-in-JS轮流坐庄。我见过太多工具的更迭,也见过太多人因为工具而放弃理解工具背后的东西。但直到今天,我才敢把一句话说出口:Tailwind这类原子化框架,正在系统性地废掉一整代前端工程师的CSS基本功。
先说清楚立场。我不反对Tailwind,我自己在多个项目里用过,甚至在某些场景下会主动选择它。问题不在于它好不好用,而在于它把“好用”和“理解”这两件事悄悄对立了起来,而且大多数人选择了前者,甚至没意识到自己放弃了后者。
最直观的症状是:越来越多的开发者看到一段样式,第一反应不是“这个布局该用什么模型”,而是“这个效果对应哪个类名”。这是一种思维路径的置换。CSS本身是一门描述性的语言,它的核心是盒模型、层叠上下文、格式化上下文、包含块、继承、优先级这些底层机制。当你写flex items-center justify-between的时候,你得到的是结果,但你未必知道为什么这个结果成立,更不知道当它不成立时该从哪里下手。
我见过太多这样的场景:一个元素怎么都不居中,开发者开始疯狂堆类名,试了十几种组合,最后碰巧好了,但说不出原因。这在手写CSS的年代是难以想象的,因为那时候你被迫去理解margin: auto为什么在块级元素里能水平居中却不能垂直居中,被迫去理解绝对定位的包含块到底是谁。这些“被迫”恰恰是基本功的来源。Tailwind把这些“被迫”消解掉了,代价是理解力的真空。
更隐蔽的问题在于层叠与优先级。原子类天生是扁平化的,一个元素上挂十几个类名是常态。这种写法绕开了传统CSS里最考验功力的部分:选择器设计、命名约定、层叠管理。BEM、OOCSS、SMACSS这些方法论当年被反复讨论,本质上是在解决“样式如何组织”这个工程问题。Tailwind给出的答案是“不要组织,直接内联”。这在组件粒度足够小的时候确实清爽,但当项目膨胀到几千个组件、多人协作、样式需要被覆盖和扩展时,扁平化的类名堆叠会变成另一种形式的意大利面条——只是面条从CSS文件搬到了模板里。
还有一个被普遍低估的点:Tailwind的抽象是有损的。它把CSS的能力裁剪成一个固定的设计令牌集合,间距、颜色、断点都是预设的。这在标准化设计体系里是优点,但当你遇到一个不在预设范围内的需求时,要么写任意值(w-[137px]这种),要么退回到自定义CSS。前者让代码失去一致性,后者让“全用Tailwind”的承诺破产。而真正的CSS能力——用clamp()做流体排版、用@container做容器查询、用:has()做父级选择、用自定义属性做主题系统——这些东西在原子类的语境里几乎被边缘化了。框架的更新速度永远追不上CSS规范本身的演进。
说到规范演进,这里有个值得警惕的时间差。过去几年CSS的进展其实非常激进:嵌套语法、层叠层@layer、容器查询、:has()、视图过渡、锚点定位。这些特性解决的都是过去必须靠预处理器或JavaScript才能绕过去的问题。但一个长期依赖原子类的开发者,很可能对这些原生能力毫无感知,因为框架已经替他封装好了“够用”的那一层。等到某天他需要写一个不依赖构建工具、不依赖框架的样式方案时,会发现自己手里只剩下一堆记忆中的类名,而没有可以迁移的底层认知。
我不是在鼓吹回到手写CSS的苦行僧时代。工程效率是真实存在的约束,Tailwind在快速迭代、设计系统落地、减少命名内耗上的价值不容否认。我想说的是,工具和能力应该是两层,而不是互相替代。你可以用Tailwind写业务,但你不应该只会用Tailwind。就像你可以用ORM,但你不该不知道SQL怎么执行;你可以用框架,但你不该不知道事件循环怎么跑。
如果你已经写了几年Tailwind,我建议你做几个简单的自测:不看文档,手写一个三栏布局中间自适应、两边固定宽度;解释一下为什么z-index有时候不生效;说出position: sticky生效需要满足哪些条件;用原生CSS实现一个主题切换而不依赖任何框架的暗色模式类。如果这些让你卡壳,那说明基本功的缺口已经出现了。
补回来的方式也不复杂。挑一个周末,把项目里某个组件的Tailwind类名全部翻译成手写CSS,逐条问自己“这行为什么生效”。去读一遍CSS规范里关于格式化上下文和包含块的章节,虽然枯燥,但那是地基。关注原生CSS的新特性,试着在不用框架的前提下实现一遍。最重要的是,在写类名之前,先在心里把布局模型想清楚——是先想“我要一个弹性容器,主轴两端对齐”,再去找对应的类,而不是反过来。
工具会一直变。十一年前流行的东西今天大多进了博物馆,Tailwind也未必能例外。真正能陪你走完职业生涯的,是那些不会因为构建工具升级而失效的理解力。原子化框架本身没有错,错的是把它当成不需要理解CSS的理由。当你把基本功外包给类名的那一刻,你就把解决问题的能力也一起外包了。