在前端社区,有很多关注与 JavaScript 文档相关的方面。但 CSS 却并非如此。我经常在加入一个 CSS 文档很少或没有的项目时感到迷茫。
尽管 CSS 相对容易编写,但维护起来却相当困难。 特异性、所有内容的全局范围以及缺乏指导很容易导致不一致性、代码重复和过度复杂化。
我一直很好奇一个真正良好文档化的 CSS 代码库是什么样子的。在这里,我将分享我的经验,以及我对良好文档化样式表的愿景。
我惊讶于有些人认为 CSS 注释并不那么重要。我想他们中没有人处理过超过 10,000 行的样式表!我经常难以弄清楚哪个 HTML 产生了特定的样式。在没有关于所做开发决策的可靠上下文的情况下,调试工作量会增加。 每分钟 WTFs 也会成倍增加。
很多时候,我花费数小时来弄清楚开发人员的意图,为什么她没有用另一种方法做,为什么这个布局看起来如此复杂。在这些“为什么”问题中隐藏着许多痛苦。
所以,我们开始吧!让我们考察一下良好文档化 CSS 代码库的 4 个主要标志。

1) CSS 技术栈和工具链
我们的 CSS 代码库中可能包含第三方库、mixin 或其他工具。查看包管理器中的依赖项列表并不能提供很多关于为什么做出这些决策的上下文,它们到底做了什么以及我们如何使用它们。
让每个人都知道为什么引入某个库或工具会很好。例如,想象一下,引入第三方库仅仅是为了解决已经过时的 CSS 问题。如果我们有这样的上下文,我们可以做出更明智的决策。
项目中有时可能会有相当多的第三方库。您是否曾经在网络上花费大量时间搜索每个库,以了解它是什么?了解或跟踪每个库的确切作用可能是一个不小的挑战。
一个良好文档化的代码库将为每个依赖项包含一个描述。也许您可以包含一条类似推文长度(140 个字符)的代码注释,解释它为什么在那里。这将使代码库中的任何其他人能够快速了解某些内容存在的原因。
我喜欢在我的 @import
位置添加这些描述。
2) CSS 约定
良好的编码约定可以产生一致、可读且明确的源代码。它们标准化应用程序的结构和编码风格,以便您和其他人可以轻松阅读和理解代码。
了解项目中是否存在任何特定的命名约定或方法非常重要(例如 BEM、OOCSS、SMACSS 或 ACSS)。我见过一些案例,其中应用了某些方法学的原则,但 实际遵循的规则根据相关开发人员的偏好进行了修改。因此,在良好文档化的代码库中,最好说明我们必须严格遵循方法学原则的程度。
这引出了 CSS 样式指南的更大问题。命名约定只是完整样式策略中的一种选择。其他部分可能是
- 代码如何分段?
- 文件如何结构化?
- 属性如何排序?
- 如何进行注释?
- 格式如何完成(缩进、规则声明)?
- 如何将 JavaScript 钩子绑定到类?
- ……以及更多规则或反模式,例如嵌套超过 3 层,避免使用 ID 选择器, 仅对实用程序类使用 !important 等。
所有这些构成了一个完整的 CSS 样式指南。我认为拥有这样的共享词汇对于保持一致性来说是一个很大的优势。
3) CSS 架构
大多数可扩展的项目在样式排序方面遵循某种类型的架构。在一个良好文档化的代码库中,应该提到项目在构建和分段样式时遵循的基本原则。
我最初受到 观看 Harry Roberts 关于管理 CSS 项目的演讲 的启发,开始探索 CSS 架构。以下是 Harry 的观点:
CSS 架构现在似乎有点流行。在过去的一年左右的时间里,您毫无疑问多次听到过它,并且有充分的理由:UI(以及构建它们的团队)正变得比以往任何时候都更大更复杂。
CSS 有许多方面使其令人头疼。它是声明性的,这意味着没有逻辑或控制流来告诉其他开发人员有关项目状态或构建的太多信息。它在全局命名空间中运行,这意味着我们会出现冲突、样式泄漏和意外的回归。它利用继承,使所有内容都变得相互依赖且脆弱。最后,不可避免的特异性模型在选择器争夺优先级时会导致问题。
因此,他 引入了称为 ITCSS 的 CSS 架构概念。如果您正在处理一个规模合理的项目,那么很可能有人已经定义了类似的原则或想法来解决这些问题。因此,在良好文档化的代码库中,我希望看到它们被写在哪里。
如果您可以回答以下问题,就可以判断架构是否得到了充分的解释:新样式或样式表应该添加到哪里?
4) CSS 组件描述和示例
一个常见的模式是将逻辑模块分离成 CSS 组件(或根据 BEM 的“块”)。其中一些可能是可重用的,一些可能不是,但重要的是它们是我们项目的构建块。因此,描述它们是什么应该成为良好文档化代码库的首要任务。
理想情况下,您应该对它们进行排列和分组、命名它们,并在它们之间建立规则以生成所有组件的概述。一个良好描述的 CSS 组件不仅包含有关组件功能的信息,还包含其他有价值的信息,例如示例 HTML 标记及其预期使用上下文。更进一步则引出了 模式库 的问题。模式库是可重用组件的集合,可用于一起创建网站。随着模块化、基于组件的架构成为趋势,它们可以带来巨大的价值。
模式库的目标是展示可以用现有模式(组件)构建的内容。但让我们看看还可以与每个模式一起显示哪些其他信息。Vitaly Friedman 在 如何将模式库提升到下一级 上分享了一个很好的总结。他指出,仅仅关注组件是不够的
模式库的主要问题之一是,虽然它们提供了组件的概述,但它们通常会留下许多需要解释的内容。组件可以以各种方式组合,一致地或不一致地。能够看到可用的按钮变体和图标以及可以使用哪些类型的表格和价格标签非常棒,但是如果您需要设计或构建一个包含所有这些组件的界面——也许还有另一个库中尚不存在的界面,该怎么办?
仅有模块列表并不能传达任何上下文或有关如何(以及如何不)使用模块的任何细节。
基于 Vitaly 的文章和 Brad Frost 关于模式库中模式的结构,这里有一些我可以想象的每个模式(组件)可能具有的想法,尽管通常有唯一的名称、代码示例和组件目的的描述。基本(基础)
- 标签或类别:分配给组件的标签或类别。开发人员可以使用“正在使用”、“需要重构”等标签来标记他们的组件。
- 响应式预览:组件的真实、可调整大小的预览,使用生产中使用的实际代码片段。或者,只是一个屏幕截图。
- 版本控制和遗留、相关或负责的团队成员:在更大的团队中,(系列)组件的所有权以及哪些团队成员一直在积极开发它们对于维护和进一步开发可能非常有帮助。
……以及更多高级功能
- 性能影响:有时 CSS 也会很重。一个性能指标或“警告标志”部分,不仅概述性能影响,还概述在错误使用模式时可能出现的任何常见错误。
- 可访问性影响:可访问性要求的指示器。某些组件可能需要更多工作才能保持可访问性,尤其是在它们与其他组件交互时。
- 相关模式:给定组件所属的相关组件或组件族的快速概述。可以使用关于何时使用组件、何时不使用以及原因的解释。
- 回退和打印预览。
… 列表可以一直延伸到适合您特定用例的任何内容。
结论
一个文档良好的 CSS 代码库可以强制执行一致性,提高可维护性,并帮助团队构建共享词汇表。它是高效 CSS 设计和开发的先决条件。此外,根据我的经验,它不可避免地会导致更好的性能。我坚信这些是项目专业执行的标志。
如果您有任何想法,请随时在下面的评论中添加,以便我们共同努力,更接近于更好的文档实践。
我遵循来自 http://codeguide.co/(由 Bootstrap 的共同创建者 MDO 创建)的所有建议和建议。那里有很多关于开发灵活、持久和可持续 CSS 的优秀信息。
此外,rscss(查看 rscss.io)对页面组件及其内部内容有很好的解释,我已经关注它一段时间了,因为它与我之前仅使用纯 CSS 构建网站的方式非常相似。
使用类似于 ITCSS 的文件夹结构来帮助组织 SASS 文件,这使得在小型和非常大型项目中使用它都成为一种乐趣。
这并不是真正地要遵循某一条规则或另一条规则,而是要将网站中的每个元素组都视为一个独立且可重用的组件。这将使代码库更 DRY,并保证每个人的理智安全。
历史注释,也曾有一些类似 CSSDOC [1] 的努力,它带来了一些好主意。我不确定该项目发生了什么,以及它是否被合并到更大的项目中。
[1] https://web.archive.org/web/20130701094049/http://cssdoc.net/
我越来越多地使用 Web Components,并且我喜欢它处理其中一些问题的方式。我通常有一个用于页面布局的文件,一个用于页面外观(h1-6、p、a 等默认值)的文件,其余部分由每个组件本身处理。每个页面都是一个新的 Web Components,因此我还有特定于页面的样式,这些样式仅在加载页面时加载。
这是一种更具组织性的思考布局的方式。我们希望能够在网站的每个页面中尽可能多地重用 CSS 或 JavaScript,但现实情况是,网站上的几乎每个页面在某些方面都不同。能够将特定页面所需的唯一 CSS 和 JS 附加到 HTML 定义中,确实有助于保持代码库的组织,并使维护变得更加容易,因为您被迫将 UI 构建为一组具有彼此之间定义接口的模块。
我目前正在开发的网站是用 Polymer 构建的,并利用组件来构建 UI 的每个部分。很明显,包含在大多数页面中的 header 元素无法满足项目不断变化的要求。进行必要的更改很简单,只需重新设计本地标记、更新本地样式,然后调整 JS 以将现有接口与新的 UI 连接起来。所有内容都位于该单个 header.html 文件中,并且每个页面都继续按预期工作。通过采用面向对象的方法并保持 CSS 和 JS 的范围,对关键元素的重大更改变得简单。
关于第 1 点,如果这是一个开源项目,那么引入依赖项的提交可能会解释为什么添加它。这将是在无需维护文档的情况下提供此类信息的好方法。
嘿,感谢您抽出时间撰写本文!我认为一些 CSS 示例/代码段将使这篇文章变得更好。
不错的文章。我之前也受到 Harry Robert 一年前的演讲的启发,从那时起,我一直在尝试编写我的 CSS 并教我的同事如何编写他们的 CSS,使其更具可扩展性和可读性,通过架构、约定和文档的力量。