我最近一直在审计大量的 CSS 代码,并且认为记下我的审计方法会很有趣。我确定根据您的应用程序的规模和您的 CSS 在幕后工作方式,有无数种不同的方法可以做到这一点,因此请您对所有这些内容保持谨慎。
首先声明几点:在我现在工作的公司 Gusto,我们的工程师和设计师都在使用 Sass 并使用 webpack 将这些文件编译成 CSS。我们的生产环境将所有这些代码最小化到一个 CSS 文件中。但是,我们的 CSS 由三个独立的域组成,因此我将它们都下载到我的桌面上,因为我想单独测试它们。
以下是这些文件的用途
manifest.css
:一个从我们所有 Sass 函数、mixin 生成的文件,并包含我们所有默认的 HTML 样式和实用程序类。components.css
:一个由我们的 React 组件组成的文件,例如Button.scss
、Card.scss
等。它和manifest.css
都来自我们的组件库代码库,并被导入到我们的主应用程序中。app.css
:一个覆盖我们的组件和 manifest 的样式集合。目前,它存在于我们的主应用程序代码库中。
下载完所有内容后,我将它们扔到一个 S3 存储桶中,然后通过 CSS Stats 运行它们。(我找不到一个我喜欢的命令行工具,所以我决定坚持使用这个工具。)CSS Stats 最酷的一点是它提供了关于网站 CSS 的健康状况和质量以及设计系统的清晰信息。它通过显示唯一 font-size
和唯一 background-color
CSS 声明的数量以及特定 CSS 文件的 特异性图表 来实现这一点。
我首先想更好地理解我们的 manifest.css
文件。正如我提到的,这个文件包含我们所有的实用程序类(例如 padding-top-10px
和 c-salt-500
)以及我们的 normalize 和 reset CSS 文件,因此它对于其他所有内容都是非常基础的。我开始深入研究 结果:

这里有一些明显的问题,例如存在 101 种独特的颜色和 115 种独特的背景色。为什么这是一个大问题?好吧,这对我来说有点令人震惊,因为我们的团队已经创建了一组 Sass 函数来输出一个非常特定的颜色数量。在我们的 Figma UI 工具包和 variables_color.scss
(它被编译到我们的 manifest 文件中)中,我们总共声明了 68 种独特的颜色

那么,这些额外的颜色来自哪里呢?我认为它们来自 Bootstrap。在我们开始构建应用程序时,我们在 Bootstrap 的样式之上仓促地构建,没有在过程中进行重构。当我们在应用程序中发现视觉不一致以及数百行代码仅仅覆盖了 Bootstrap 时,这种情况开始变得痛苦。在一个相当英勇的 CSS 重构中,我从我们的主应用程序中删除了 Bootstrap 的 CSS,并将它存档到 manifest.css
中,等待着有一天我们可以回到它并重构它。
这些额外的颜色可能来自那个旧的 Bootstrap 文件,但可能值得进一步调查。无论如何,对我来说,真正的问题是 **我对设计系统的理解与前端的理解不同**。这是一个大问题!如果我对设计系统的理解与 CSS 的工作方式不同,那么工程师和设计师就有很大的可能采用错误的模式,并且混淆会蔓延到整个组织。想想额外的膨胀和缺乏可维护性,更不用说其他影响了。
我正在阅读 Matthew Ström 撰写的 设计系统面向谁?,当他引用了 Julie Ann-Horvath 的演讲时,我引起了注意,她被认为说:“设计系统只有在生产中才存在。”遵循这种逻辑,很明显我以为我们拥有的设计系统实际上并不存在。
回到 manifest.css
,这个文件的特异性图表应该完全是逐渐的,然而却有一些明显的峰值表明可能需要重构一些 CSS 代码

接下来是我们的 components.css
。请记住,这是我们组件样式来自的文件,因此我事先认为它一定会比我们的 manifest 文件更混乱。将它扔到 CSS Stats 中会返回以下内容

CSS-Stats 显示了一些相同的问题——例如字体大小过多(那个巨大的字体大小到底是怎么回事?)——但也有太多自定义颜色和背景颜色。在我开始之前,我已经对这个 CSS 文件最大的问题有所预感,我认为这个问题在这个数据中根本没有显示出来。
让我解释一下。
我们的大量组件曾经是某种形式的 Bootstrap 文件。例如,我们的 Accordion.jsx
React 组件。它导入一个 accordion.css
文件,该文件随后与所有其他组件的 CSS 编译成一个 components.css
文件。这样做的问题是,一些 Accordion
样式会影响比该组件本身更多的东西。来自这个文件的 CSS 会渗透到其他模式和类中,而这些模式和类并不仅仅与一个组件绑定。这有点像我们系统中的毒药,会影响我们的团队,因为它使得难以可靠地更改单个组件。它还会导致一个非常脆弱的代码库。
所以我想说的是,像 CSS Stats 这样的工具对于帮助我们检查 CSS 健康状况的核心生命体征非常有用,但我认为它们永远不会真正捕捉到全貌。
接下来是 app.css
文件

这是我们的设计系统团队目前正在努力理解并希望重构为一系列灵活且可维护的 React 组件的“巨石”——这些组件可以被其他人反复重用。
让我担心这个代码库的是它的特异性。当 manifest.css
或我们的 components.css
中发生更改时会发生什么?这些样式会被巨石中的样式覆盖吗?我们导入到新项目中的漂亮整洁的组件样式会发生什么?
随后,我不知道我从哪里偷来的,但我最近一直在说这句话——你应该总是能够预测你的 CSS 会做什么,无论是单行代码还是一个巨大的交织在一起的样式代码库。这就是设计系统的全部意义——为未来设计和构建可预测的界面。如果我们的编译后的 CSS 中包含所有这些不可预测且不可知的部分,那么我们需要召集大家一起解决它。
总之,我将其中一些数据扔到一个 Dropbox Paper 文档中,确保我们开始解决这些问题,并随着时间的推移逐渐改进。今天看起来像这样

您是如何进行 CSS 审计的?您的团队是否进行 CSS 代码审查?您有什么建议的技巧和提示吗?请在下方留言!
这正是我构建 Project Wallace 周围的所有工具的原因!它是 CSS stats 之上的一个额外的层,因此您可以跟踪 CSS stats 的历史记录。查看 https://www.projectwallace.com,也许还有我一直跟踪的 CSS Tricks 网站:https://www.projectwallace.com/teamwallace/css-tricks
此外,您提到了没有找到喜欢的 CLI 工具。也许 wallace-cli 可以胜任这项工作?https://github.com/bartveneman/wallace-cli.
除了对我们的部分使用 StyleLint 进行 linting 之外,我们还使用 gromit-cli (https://github.com/bartveneman/gromit-cli) 来验证我们的最终 CSS 是否没有输出比我们颜色设置中指定的更多颜色。
最后,使用表格来快速概览最后一段的想法很棒。我很乐意在 Project Wallace 中构建这样的功能。
我的天啊……这个项目太棒了。谢谢您!我一定会开始使用 Wallace 跟踪我的项目。
有了所有这些 CSS 代码,我认为将它分成一个基础文件,并根据需要按模块加载,而不是让访问者在最开始就下载所有代码,这样会更有意义。也许您已经在这样做,而这些文件只是为了分析而组合在一起的。
我唯一避免交叉依赖的方法是使用 CSS-in-JS、命名约定 .viewName-Component[-componentPart][–modifier] 或使用影子 DOM。影子 DOM 目前还不可行。类似 BEM 的约定很冗长,不支持版本控制(同一个应用程序中的多个视图版本)。
所以……任何时候都选择 CSS-in-JS。
Robin,好文章!
我曾经在 Yelp 的核心前端团队工作过,我认为那里的统计数据也讲述了一个类似的故事 https://cssstats.com/stats?url=https%3A%2F%2Fwww.yelp.com%2Fbiz%2Fgary-danko-san-francisco&ua=Browser%20Default
我有机会接触到其他代码库(更小或类似大小),这些数字看起来也并没有好多少。
当然,一些缩放变量(例如进行更改的工程师数量)和代码库的年龄需要考虑,但我认为技术栈在这方面起着至关重要的作用。
在我看来,传统的预处理器 + 命名约定 + 设计系统(通常是模型而不是真实来源/代码)无法扩展。
我认为“设计令牌”系统 + 使用原子 CSS 和扁平化特性的组件可以解决统计数据中突出的许多问题。我们只需要合适的工具,也许可以默认获得这些好处。
这个工具可以是 CSS in JS 库,但它不一定是那样。
例如,我开始了一个实验,它介于 CSS 模块和 CSS 块之间,我称之为确定性样式表 (DSS)。我会在这里留下一些链接,并欢迎你提供任何反馈意见。
设计令牌的示例 https://twitter.com/giuseppegurgone/status/1019431376020561921
更多关于 DSS 的信息 https://survivejs.com/blog/dss-interview/
我目前正在 blacklane.com 上进行 CSS 颜色审计,但我缺少一个工具来显示 src/ 文件夹中的所有颜色。
所以我写了一个:https://npmjs.net.cn/package/colors-in
也许这会有所帮助!