最近在与 Ben Frain 的 ShopTalk Show 中,CSS 缩放这个话题被多次提及。Ben 对此话题进行了深入思考,甚至写了一本完整的书,名为 Enduring CSS,这本书围绕着完整的 ECSS 方法论展开。
他谈到,对于大规模样式设计,本质上存在两种解决方案
- 完全隔离
- 完全抽象
完全隔离 是某种在您设置的边界(例如组件)内编写样式的方法,这些样式不会泄漏到外部或内部。
完全抽象 是某种编写全局样式的方法,但这些样式非常通用且可重用,因此不会产生任何意外的副作用。
完全隔离可能来自 .vue
文件中的 <style scoped>
、CSS 模块(其中 CSS 类选择器和 HTML 类属性是动态生成的无意义字符)、或 CSS-in-JS 项目(例如 glamerous)。即使严格遵守命名约定(例如 BEM)也可以算作一种完全隔离的形式。
完全抽象可能来自像 Tachyons 这样的项目,它为您提供了一组固定的类名用于样式设计(Tailwind 就像它的可配置版本),或一个编程工具(例如 Atomizer),它将特殊命名的 HTML 类属性转换为包含其所需内容的样式表。
问题出在中间地带。它使用了命名方法,但没有严格遵守。它在组件中使用了一些样式,但也使用了一个全局样式表来执行其他随机操作。或者,它让许多开发人员参与到一个没有严格规则的样式系统中,该系统混合了全局样式和作用域样式。任何 不断增长 的样式表都是如此。通过删除一些未使用的样式来解决它并不是真正的解决方案(原因在此)。
请注意,网络是一个很大的地方,并非所有项目都需要缩放解决方案。一个拥有数百名开发人员且需要维护数十年的庞大代码库绝对需要。我的个人网站不需要。我遇到过很多样式问题,但我从未因为这些问题而陷入困境,以至于需要实现像原子 CSS(及类似方案)这样严格的东西来完成工作。在我参与过的任何工作中也都没有遇到过。不过,我看到了它的好处。
想象一下 Twitter.com 十年来的规模!Nicolas 发布了一个很棒的帖子,他在其中比较了 Twitter 的 PWA 和 Twitter 的传统桌面网站。
传统网站的 CSS 是数百人在多年里直接编写 CSS 的结果。特异性冲突、冗余、摇摇欲坠的纸牌屋无法修复。其结果是极其低效且容易出错的样式,给用户和开发人员都带来了困扰。
我喜欢这篇文章和主题本身(最近在 CSS 中,这是我思考最多的问题)。但是
我真的很喜欢这种中间地带。我认为它是最好的!
我一直想知道为什么没有一个特定的 css 代码词可以停止级联……这样我们就不用覆盖对元素产生负面影响的级联样式。
我开始阅读他们提到的《Enduring CSS》这本书。虽然作者所说的大部分内容都与我的想法背道而驰(使用了大量冗余代码),但我理解他的理由,这似乎使得这种方法适用于需要积极维护的大型项目。它有点像大量不同方法的混合/挑选。在某些方面它是 DRY 的,在某些方面它不是。
我花了很多时间才理解,最后我明白了。
感谢分享这篇帖子,继续努力。
我认为我们需要以多层的方式定义样式。
全局
品牌
应用
功能
模块(复合组件)
组件
然后问题就变成了每一层如何在它下面的层(级联)上断言自身。
能够有一种简单的机制来定义这些层中变量的作用域并在特定上下文中覆盖它们会很好。
另一个问题是如何使您的组件、模块和功能与它们实现的位置分离。如果您的组件具有关于在侧边栏中呈现时如何显示的样式规则,那么它就不一定像它可能的那样独立。我认为在父模块/功能中进行样式定制更有意义,因为父模块/功能自然包含/了解其子元素。但问题是,当子组件的样式契约发生变化时,您必须跟踪父元素中的这些定制。
广泛的挑战在于,当我们尝试使 css 适应更面向对象的模型时,我们创建了难以调试和维护或根本不直观的抽象。编写一堆可以生成重复类或自动定义命名空间或任何其他数量事物的混合可能看起来很优雅,但是如果您必须将该代码交给开发人员,则可能会遇到问题。
我查看了一些解决方案,并认为“太好了,我绝对可以使用它”,然后我想“50 名海外开发人员、实习生、新的助理开发人员以及正在转向 UI 的 C 开发人员,他们都对 CSS 了解有限,将如何理解这一点?”在某些时候,您必须在优雅和代码重用与可读性和直观性之间取得平衡。这并不是说我们不应该努力提高每个人的知识水平,但有时我们可能会陷入抽象地狱并减慢每个人的速度,因为顶部的摇滚明星认为这是一个好主意。
最终,能够找到适用于产品不同范围和产品生命周期的各种工具和技术会很好。我可以看到实用程序类对于快速原型设计和故障排除非常有用,但我不想将它们用于生产。我一直很喜欢使用 CSS 模块,但它们的编译速度非常慢,并且在 SPA/React 环境之外利用它们也存在一些挑战。SASS 非常好,我喜欢它可以为您的 CSS 带来的结构和组织,但它可能会很快失控并变成混乱的局面。BEM 总是遇到同样的问题——命名很难。CSS-in-JS 样式无法在非 SPA 项目中共享……等等。
我有一个好主意! 让我们使用普通的旧 CSS!(停顿以产生效果……只听到蟋蟀的叫声。)
不,我是认真的,伙计们!我们一直在寻找那片更绿的草地,因此我们中的许多人(包括我自己……很容易证明我近乎狂热地使用不再是 CSS 但也不是 BOOTSTRAP 的W3CSS)一直在寻找并找到下一个最佳选择。如果你稍微想一想,你就会意识到,有了所有这些 xSSes(excess-ess-es,双关语最初并非有意,哈哈),以及 thisSS 和USS、MESS、GPSS,可能甚至还有所有 .js 前处理、后处理,我认为甚至还有产后处理器的LMNOPSSes,好吧……糟糕!有了这么多种口味,当然我们最终都会找到完美的“更绿的草地!”
哦,但我们必须学习更多东西(在这里你认为 CSS 变得太大了),比如 mixin、moxin、boxin 和 toxin。再学习一下 CSS 格式,然后……呃!是的,我知道:但不要 TL;DR 我,我快完成了。但重点是让你感到有点筋疲力尽。我的意思是,你必须承认:那里有很多CSS/JS 替代方案。
而且大多数,如果不是全部的话,它们实际上只能帮助你使用原始 CSS 做到你可以已经做到的事情,但速度更快或代码更少,这二者也是一回事。
CSS 不断更新和修订。实际上,即使我喜欢 W3CSS,我也在回归我的根源,可以这么说……我们的根源,实际上。回到 OGCSS?好吧,好吧……太过了。回到原始的 CSS。说实话?我真的很喜欢我看到的东西。再试一次。你可能会像我一样,感到惊喜。
保重,以及
编码愉快!
Michael C