
原文载于 zendev.com。
最近,「CSS in JS」获得了大量的关注。原因很简单:CSS在运行在公共命名空间中,可能引发不好的副作用,导致代码混成一团(译注:原文是意大利面式代码),给维护代码库造成极大的困难。于是人们用JavaScript来解决这个问题,把所有的代码(CSS、JS)封装进模块里然后使用诸如Webpack之类的工具将一切缝合起来。看!JavaScript也可以处理CSS了,为什么我们不把所有的CSS也放进JavaScript里然后封装成模块呢!
有一个真正亟待解决的问题--人们确实可能会写出可怕的,难以维护的,堪称灾难级别的CSS。事实上,这样的事情非常普遍。别误解我,我喜欢JavaScript……但作为这个问题的解决方案,「CSS in JS」就像是用你最喜爱的锤子换掉你老旧的螺丝刀。当然,(用锤子)你可以把螺丝钉更深地钉进墙里,但是,当初你用螺丝刀取代指甲拧螺丝时不也消灭了许多困难而富有价值问题吗?
CSS与JavaScript的关键差异
让我们看看CSS专注解决的问题与Javascript专注解决的问题之间有哪些关键性的差异吧。
结构化/行为化 Vs 图形化
支持「CSS in JS」的一个常见论据是“我们过去认为分离关注点很重要,但是看看JSX!”。这个论据用这个(其本身也充满争议)的例子来论证清晰地分离关注点是错误的,将CSS写入JS内也同样可以提升生产力。
这个观点忽略了结构化/行为化属性与图形化属性之间的差异。当关注点之间事实上是分离的时候,分离关注点是确实有价值。我从两个方面解释,JSX提升了生产力的原因是结构和行为是紧密相关的--大量的Javascript逻辑必须操作HTML结构实现,所以分离两者只会增加理解难度,而非减少。
对比很大程度上是由CSS实现的图形化属性。CSS与HTML并非紧紧联合而是松散的组合--这也是为什么人们可以直接给出一个产品所有功能的线框图而不需要附加很多样式。把你的CSS放入你的逻辑代码里是一种不必要的耦合,只会增加理解难度。
松耦合 Vs 紧耦合
耦合的概念为我们做出权衡提供了另一个思考角度。人们广泛认可:设计松耦合的系统可以提供更好的扩展性、可维护性和可阅读性。样式仅仅和HTML结构有松耦合--视觉上非常相近的UI元素可能在底层结构、逻辑甚至行为表现上有着显著的不同。相对的,交互元素的交互逻辑必定紧紧依赖操作HTML结构。
「CSS in JS」造成的新问题
视觉一致性
另一个Javascript的逻辑结构性质与CSS的图形/视觉性质之间关键的不同是:对于一致性的需求。在Javascript的世界里,如果你能把每一个组件做的更独立一点,那么代码质量更高。如果适当的封装代码,你甚至可以把每一段Javascript代码片段独立处理,而不需要关注他们相互之间内部的一致性。
与你的视觉输出相比较--如果每一个组件都是与其他组件完全独立的视觉呈现,你的网站或者应用将呈现灾难性的混乱。当然,每一个组件都有其独有的属性,并且这些属性之间应该相互独立以防泄漏污染彼此,但对你的站点而言,视觉的一致性是一项非常重要的需求。这也是使用CSS样式表的核心原因之一,一个难以理解的、失控的样式表可以说是一场灾难,而恰当地使用CSS,它则会是一个非常有力的工具。
代码重用
在软件开放领域,保证事情‘DRY’(Don‘t repeating yourself,意为不要让自己重复做已经做过的事)并且写出可复用的代码通常被认为是一种非常好的练习。它可以使得我们每次只需要修复与更新一个地方而不是在整个代码库内大量重复的地方。
使我困惑的是,「CSS in JS」提倡这个观念(DRY)是必要的,但书写样式时又采用“复制&粘贴”的方法。如上文提到的,在你的网站或应用内保证各种元素的视觉一致性是极其重要的。这意味着如果每一个组件只需要对自己的样式负责,最终你会制造数量庞大的重复。当你的品牌决定更换它的设计语言时会发生什么呢?如果你想要引入一个新的主题,甚至只是隐隐地改变你的应用的界面以跟上现代设计的实践。你将不得不深入到每一个组件去实现这些改动。从可维护性角度看,这种方案造成了可维护性的噩梦。
真正的解决之道:更好的CSS实践
希望到了这里,我已经说服了你相信「CSS in JS」是一个糟糕的策略,但仍然有一个真正的问题需要解决。这个概念会被提出正是因为过去有着数量庞大的,可怕的,难以的维护的CSS样式表。 “只添加CSS”和盘根错节的样式表会导致每一个改动都充满了风险,这在生产中令人无法控制。我曾经也陷入过这样可怕的境地里。但幸运的是,已经有成千上万聪明的人在思考并解决这个问题。真正的解决之道并不是提供一个Javascript之锤然后引发另一个问题,而是要意识到:精巧地构建CSS是一件真正的工程,一项与写Javascript有着截然不同的系统方法和需求的工程。而且创建简单有效,可维护,可扩展的样式表已经有了可供参考的最佳实践。
如果你在这个领域还是萌新,你可以参考以下实践方案:OOCSS, SMACSS, BEM, ITCSS, 和 ECSS. 其中每一个方案的背后都有着大量的思考,但和每一个工程问题一样,世上并没有“完美的解决之道”,只有不同的权衡方案。采用其中任何一种实践方案都可以提升你的CSS技巧,助你摆脱样式表的地狱。关键在于承认这是一门工程学科,理应获得其他工程学科同等的关注和严谨对待。
P.S. — If you’re interested in these types of topics, I send out a weekly newsletter called the ‘Friday Frontend’. Every Friday I send out 15 links to the best articles, tutorials, and announcements in CSS/SCSS, JavaScript, and assorted other awesome Front-end News. Sign up here: https://zendev.com/friday-frontend.html
原载于 zendev.com 2017-9-11。
译者按:
作者的观点我有相当一部分的赞同,所以才选择翻译了这篇。虽然9月的文章现在看似乎有点过时了,但一些问题是始终存在的。纯粹的分割每一个组件并在JS中书写CSS会造成很大的割裂。现在React方向已经有了一些更有机的方案比如CSS in module。仍然书写CSS文件,并通过一些方式实现样式的服用,又兼具了CSS in JS的书写特性。但在实践上,仍有一些道路要走,一些开发仍然会完全独立所有组件,将一些重复的样式写的到处都是,非常可怕。前端方面目前的问题就是更迭太快,开发者疲于追逐新的技术,甚至一个技术还没有很好的实践下去,又开始使用新的技术。最终技术虽然在更迭,代码的质量依然是一样的缺乏可维护性,可扩展性。无论使用什么技术,深入思考最佳实践方案,才是进步之道,盲目追逐新颖的框架与技术,可能只是囫囵吞枣,最终什么营养也没有吸收进去。
网友评论