开发者 Ben Frain 曾说过,编写 CSS 代码很容易,但很难扩展和维护。 本文介绍了用于解决此问题的解决方案集。
OOCSS

- 结构和设计的分离
- 容器和内容的分离
使用此结构,开发人员可以获得可以在不同位置使用的通用类。
在此步骤中,有两个消息(像往常一样,好消息和坏消息)
- 好消息:通过重用代码来减少代码量(DRY 原则)。
- 坏消息:复杂的维护。 当您更改特定元素的样式时,您很可能不仅需要更改 CSS(因为大多数类是通用的),还需要在标记中添加类。
此外,OOCSS 方法本身没有提供特定的规则,而是提供了抽象的建议,因此该方法在生产环境中的最终实现方式会有所不同。
正如发生的那样,OOCSS 中的理念启发了其他人创建他们自己的、更具体的代码结构方式。
SMACSS

SMACSS 代表 CSS 的可扩展模块化架构。 该方法的主要目标是减少代码量并简化代码维护。
Jonathan Snook 将样式划分为 5 部分
- 基本规则。 这些是主要网站元素的样式 - body、input、button、ul、ol 等。 在本节中,我们主要使用HTML 标签和属性选择器,在特殊情况下使用类(例如,如果您有 JavaScript 样式的选择);
- 布局规则。 这里包含全局元素的样式,页眉、页脚、侧边栏等的大小。 Jonathan 建议在选择器中使用 id,因为这些元素在页面上不会出现超过 1 次。 但是,本文作者认为这是一个不好的做法(每当 id 出现在样式中时,世界某处的小猫都会感到难过)。
- 模块规则。 可以多次用于单个页面的块。 对于模块类,不建议使用 id 和标签选择器(分别用于可重用性和上下文无关性)。
- 状态规则。 在本节中,规定了模块和网站基础的各种状态。 这是唯一允许使用“!important”关键字的部分。
- 主题规则。 您可能需要替换的设计样式。
还建议为属于特定组的类输入命名空间,以及为 JavaScript 中使用的类使用单独的命名空间。
这种方法使编写和维护代码变得更加容易,并且吸引了大量的开发人员。
原子 CSS

使用原子 CSS,为每个可重用属性创建一个单独的类。 例如,margin-top: 1px;
假设创建了一个类 mt-1
或 width: 200px;
类 w-200
。
这种样式允许您通过重用声明来最小化 CSS 代码量,并且在更改技术任务时,相对容易地将更改输入模块,例如。
然而,这种方法有明显的缺点
- 类名是描述性属性名,而不是描述元素的语义性质,这有时会使开发变得复杂。
- 显示设置直接位于 HTML 中。
由于这些缺点,该方法遭到了大量批评。 然而,该方法对于大型项目可能有效。
此外,原子 CSS 用于各种框架中来指定校正元素样式,以及其他方法的某些层中。
MCSS

MCSS 是多层 CSS。 这种代码编写风格建议将样式分成几个部分,称为层。
- 零层或基础。 负责重置浏览器样式的代码(例如 reset.css 或 normalize.css);
- 基本层包含网站上可重用元素的样式:按钮、文本输入框、提示等。
- 项目层包含单独的模块和“上下文” - 元素根据客户端浏览器、查看网站/应用程序的设备、用户角色等的修改。
- 装饰层以 OOCSS 样式编写,对元素的外观进行细微的更改。 建议只保留影响外观且不会破坏网站布局的样式(例如颜色和非关键缩进)。
层之间交互的层次结构非常重要
- 基本层定义中性样式,不会影响其他层。
- 基本层的元素只能影响其层的类。
- 项目层的元素可以影响基本层和项目层。
- 装饰层以描述性 OOCSS 类(“原子”类)的形式设计,不会影响其他 CSS 代码,并在标记中选择性地应用。
AMCSS

AMCSS 是“CSS 的属性模块”。
让我们看一个例子
<div class="button button--large button--blue">Button</div>
这样的类链并不简单,所以让我们根据属性对这些值进行分组。
这里发生了什么
<div button="large blue">Button</div>
为了避免名称冲突,最好在属性中添加命名空间。 然后我们的按钮代码将采用以下形式
<div am-button="large blue">Button</div>
如果您使用验证器检查代码,并且它不喜欢 am-button
属性,您可以在属性名前缀 data-
。
使用了一个鲜为人知的选择器“~=”(IE7+),它充当类属性:它选择其属性值包含指定单词(以空格分隔)的元素。 因此,形式为 [class~="link"][class~="button"]
的选择器类似于选择器 a.link.button
。 即使按特异性,因为类和属性的选择器特异性彼此相等!
相应地,CSS 代码
.button {...}
.button--large {...}
.button--blue {...}
转换为
[am-button] {...}
[am-button~="large"] {...}
[am-button~="blue"] {...}
如果您认为此代码太不寻常,您可以使用不太激进的 AMCSS 形式
<div am-button am-button-large am-button-blue></div>
FUN

FUN 代表选择器的扁平层次结构、实用样式、命名空间组件。
每个字母后面都有一定的原则
- F,选择器的扁平层次结构:建议使用类来选择项目,避免无故级联,并且不要使用 id。
- U,实用样式:鼓励创建用于解决典型化妆任务的服务原子样式,例如,
w100
用于width: 100%;
或fr
用于float: right;
- N,命名空间组件:Ben 建议添加命名空间来指定特定模块元素的样式。 这种方法将避免类名重叠。
一些开发人员注意到,使用这些原则编写的代码非常方便编写和维护; 在某种程度上,作者从 SMACSS 中汲取了精华,并以简单明了的方式阐述了这种技术。
这种方法对项目和代码结构提出了很多要求,它只确定了记录选择器的首选形式以及它们在标记中的使用方式。 但在小型项目中,这些规则足以创建高质量的代码。
结论
正如您所看到的,这些方法中没有一个是理想的。 因此,这些方法都不是绝对规则 - 您可以从头开始采取一种方法来创建您自己的东西,或者从头开始创建一种新的方法。
很好的回顾,谢谢。
你用什么来制作你的图表呢?
感谢这篇文章!创建一个调查以了解开发人员中最常用的方法会很棒。
非常感谢你的这篇文章。
我已经了解了 OOCSS 和 SMACSS,但其他方法不太熟悉。
那 BEM(块、元素、修饰符)呢?
我认为 BEM 应该是最流行的 CSS 组织方法之一。
我很惊讶没有看到我认为最流行的方法之一:BEM(块-元素-修饰符)及其衍生方法。
http://getbem.com/
不过文章很棒,谢谢 :)
我认为对于原子 CSS 提到的“重大缺陷”实际上是优势。
元素的“语义性”通过元素标签(a、p、header、nav 等)和模板结构中组件的名称(card.tag 等)充分定义。
有些人发现,当他们在标记中看到显示设置时,更容易理解它们,而不必深入 CSS 查看设置在哪里定义。
我以为这里会提到一些关于 ITCSS 的内容。到目前为止,我非常喜欢它!
你可以在这里看到 ITCSS http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528
您好,Inessa,
我认为值得一提的是,您提到的关于 **原子 CSS** 的缺点仅存在于那些接受“关注点分离”(语义类名)* 的人身上。请参阅“被认为有害的领导者意见”。
我也有同样的想法。语义类名究竟如何有利于项目?它们不会对搜索引擎、最终用户或辅助工具有任何益处。那么为什么这被认为是一个缺点……甚至是一个“相当大的”缺点呢?
Thierry,我很抱歉。ACSS 确实很酷……
@Ben 当然,使用语义上有意义的 CSS 类对用户没有优势。这里的优势在于 *开发者*:使用诸如
submit-button
之类的类而不是c-green ph-10 pv-5 m-5
,你可以更清楚地了解某个东西的 *用途*。如果你将模板分解成模板引擎的单独文件,那么我认为原子设计很有意义。你可以通过组件的名称了解上下文,并准确了解它使用原子类在做什么。
你在文章开头提到了 Ben Frain 的评论。他可能会欣赏你提到 ECSS。他 写了这本书。
我还建议你研究一下 BEM 和 ITCSS。
CSS 模块也缺失了。我相信它是当前“组件元数据”中的圣杯。
我从未在个人项目中使用过原子 CSS,但我不得不定制现有原子 CSS 项目的外观。这太糟糕了!
由于开发人员没有声明语义类,因此没有可以附加样式规则的内容。想改变某个元素的颜色?太可惜了。它被定义为橙色,它将一直保持橙色。
唯一覆盖 CSS 的方法是使用兄弟类选择器(如果其他橙色元素没有相同的兄弟类)或层次选择器。两者都很糟糕,都是黑客行为。 *发抖*
我们在项目中使用过一段时间 FUN 的一种形式。并且找到了可以在每个网站、表单、设计等中使用的结构的通用样式集。这成为我们的 **基础**。这个基础随着时间的推移不断迭代和改进。
然后我们发现,在它的基础上,为网站提供一个默认的 **网站** 样式集是件好事。标准的配色方案、字体格式等,以及特定于网站的媒体查询。
接下来,一个简单的 **额外** css 文件,从一开始就目的明确,永远不需要任何顺序或级联。这意味着我们可以向此文档添加任何自定义内容,而无需担心未来的维护,因为我们都知道这里的样式本身并不依赖于任何级联效果。因此,所有内容都可以轻松地添加到文档的顶部,而无需担心。(更少的担心使工作更快)
最后,**页面** 特定样式。例如,主页有一个在其他地方没有使用的有趣元素,把它放在 home.css 文件中,完成了。这样就避免了任何对内联样式的需求,或对其他更长或更通用的 css 文件的混乱插入。并且,单个页面的任何有趣样式需求在未来都可以轻松管理。
基础 > 网站 > 额外 > 页面
不过它没有形成一个可爱的缩略词。(FoSEP?:P)最糟糕的是,它有 4 个 http 请求,经过优化后是 2 个(FSE,然后是页面单独请求),或者将来使用 HTTP2 来解决。
你对 React 中将 CSS 保持在组件旁边的趋势有什么看法?
第一次尝试是使用内联样式完成的,但它已被更复杂的工具(如 Aphrodite)取代,Aphrodite 生成标签并将 CSS 放在其中,以供组件加载。
不错的文章。一个地方收集了惊人的 CSS 信息。
以下内容都是隐含的,恕我直言。
这是一篇很好的回顾,但我认为从现代“组件化”和局部作用域的 CSS 开发的角度来看,这些方法都有些过时了。BEM 在这里没有被提及实际上很值得注意,尽管在组件方面它是最棒的。
如果有一种方法必须 *消失*,那就是原子 CSS。它的小优势(例如,更小的样式表)被巨大的缺陷所掩盖,主要是
它将样式代码与用于生成类的原子 CSS 框架紧密耦合(不,不仅仅是 Tachyons);
为了简洁,用于命名类的约定隐含着学习曲线,而且往往不清楚(
b-10
是指边框,还是指bottom
属性?w-20
框是 20 像素大,还是em
,还是点,还是 %?);Atomizer 解决了上述问题,但结果当然会导致更长的类名,并且会导致下一个问题:对于每个元素,你最终可能会有十几个类名,可能全部挤在一行(即,难以阅读);
当然,你可以将 HTML 属性分成几行,但这反过来又会影响 HTML 整体的可读性;
当 CSS 模块规范中添加新的模块时,它将无法很好地适应;
媒体查询使一切复杂化;
它具有误导性,因为它导致了开发人员/设计师 *看到结果* 的表示,但它 *并不总是呈现给用户的方式*:类似
bg-blue
的东西在电子墨水显示屏或屏幕阅读器上会失去其所有意义。它促使开发人员只使用原子类,而忘记了可以用于周围元素和后代元素的引用和命名空间的语义类(例如,标题后的第一个段落,或表格中的交替行);
因此,它将 *表现逻辑* 从 CSS 转移到 HTML,甚至 JavaScript,在那里你需要生成动态内容;
它没有为更复杂的元素状态提供明确的解决方案(即,不仅仅是
:focus
或:hover
,而是诸如“已选中”或“邮件已发送”之类的东西)。这只是我想到的一些问题,可能还有一些遗漏。但结论是:原子 CSS 很难学习、使用和维护。
如果你喜欢它,我并不是说你不能是我的朋友,但是……不要让我和你一起开发东西。:)
它可能不是灵丹妙药,但我认为这取决于你的需求和你的环境。作为设计师和开发人员,我发现它作为一个易于移植的起点,非常适合新项目和开发过程中的迭代阶段的快速原型设计。这些天我甚至忘记了 Photoshop 是什么。特别是在基于组件的单页应用程序中,我发现它可以快速构建组件。这些组件本身充当语义引用,如上所述,有时元素本身可以提供足够的语义信息。
我建议你阅读这篇文章
你会看到,缩写并不总是被使用。你所看到的缩写需要学习曲线的问题有些愚蠢。你只需要一个每个缩写的文档化参考,一旦你使用它一段时间后,参考就变得不再必要了。学习曲线并不陡峭,事实上它非常基础。
我个人不使用缩写,我喜欢使用 BEM 来传达在构建单体组件时块的嵌套方式。我遵循类似于这种风格
http://solid.buzzfeed.com/
我在文章出来的时候就读过了。
学习新语法的困难是真实存在的,而且非常普遍。它需要所有开发人员的投入。也就是说,你不能偶尔使用 Atomic CSS,否则你将会忘记你使用的约定,并且被迫重新学习它们。
而这正是我工作的公司(主要提供外部咨询,经常需要处理在其他地方构思的代码库)会发生的事情。
幸运的是,我们从未遇到过使用 Atomic CSS 开发的项目,因为我们需要学习另一种工具(可能是文档不足)的设置才能进行任何工作。即使我们使用 Atomic CSS,他们也可能使用了不同的类约定。
实际上,罪魁祸首是 Atomic CSS 在 CSS 之上引入了另一个任意的抽象层。这层需要学习并一致地使用,而我们本可以使用这些资源来立即提高生产力。
当然,我们遇到过更糟糕的情况,比如 8000 行长的 CSS 文件,里面充满了像意大利面一样的类和声明,还有大量的 id 和 !important 东西。这些东西会让你躲在角落里哭泣。Atomic CSS 至少意味着要努力组织代码。
但对于我们从头开始的项目来说,经典的、组件驱动的 SCSS 代码库仍然对我们来说更自然。
Atomic CSS 是我现在在工作中使用的。我创建并维护一个 ASP.NET web 应用程序。对我来说,它现在似乎是最有效的,因为我们有很多程序员不太了解 SASS 或 CSS,他们经常需要联系我,向我提问,但是现在我为他们设置了一套简单的实用程序类,他们可以构建东西,然后让我一个人呆着。:)
另一种有用的方法是 Harry Roberts 的 ITCSS。关于它的信息不多,但 Lubos Kmetko 在 xfive 上的一篇文章提供了很好的概述(https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/)
感谢你发表这篇文章,比较了不同的方法。
我偏爱 Atomic Design 的 CSS 方法。
我最近开发了自己的 Atomic Design 风格的 CSS 框架。这个框架源于我需要一种快速的方法来开发 HTML 原型,而无需花时间在 CSS 开发上(这就是它使用大量实用程序 CSS 类的理由)。
请在 GitHub 上查看它,并随时创建分支或提供一些反馈。我正在开发一些文档。
https://github.com/celummis/AtomicAgnosticCSS
我也很怀念 Harry Roberts 的 ITCSS。一年前我在一个大型 SCSS/SASS 项目中采用了它,我真的很喜欢它
我个人使用 ITCSS 作为架构,使用 BEM 作为命名约定,并从 SCMACSS 中借鉴了一些命名空间的想法。效果非常好。当然,所有的功劳都要归功于 Harry Roberts。他的文章和演讲值得一看。
https://csswizardry.com/
http://rscss.io
非常易读的标记(即不是 BEM),并且样式非常安全,不会泄漏太多。与 CSS Modules 的作用域相结合,看起来相当不错。