【发布时间】:2010-10-14 00:46:24
【问题描述】:
Web 开发领域似乎出现了一个新的流行语:面向对象的 CSS。
从表面上看,这让我觉得这只是将最佳实践包装在一个朗朗上口的口号中。我理解并完全尊重这场运动背后的意图,但还有更多吗?
有没有人有任何进一步的见解可以使这种方法与众不同,因为它更可信,或者我应该把它作为一个提醒,以确保我正确地继承和级联我的类?
【问题讨论】:
标签: css oop methodology oocss
Web 开发领域似乎出现了一个新的流行语:面向对象的 CSS。
从表面上看,这让我觉得这只是将最佳实践包装在一个朗朗上口的口号中。我理解并完全尊重这场运动背后的意图,但还有更多吗?
有没有人有任何进一步的见解可以使这种方法与众不同,因为它更可信,或者我应该把它作为一个提醒,以确保我正确地继承和级联我的类?
【问题讨论】:
标签: css oop methodology oocss
吸引人的流行语和合法的设计方法。
虽然我认为其中的一些想法有点幼稚,因为它们往往会忘记“客户端会随其变化”的 Web 开发范式。
【讨论】:
它确实是那些有争议的事情之一,例如表格与 div 等。
在我看来,有很多开发人员在 OO 中根深蒂固,以至于他们试图将其应用到所有东西上,首先是 Javascript,现在是 CSS。不要误会我的意思,JavaScript 也有 OO 元素,但我跑题了。
由于 CSS 本身已经是一个流行词(所有雇主都希望使用 web 2.0 CSS 方法),许多新开发人员正在发现它。这不是一件坏事,但是作为开发人员,他们做了他们最擅长的事情并试图改进 CSS。在开发人员的心目中(我是一名开发人员),根据 OO 原则组织 CSS 非常有意义 - 因此是新的流行语。
最终我想说的是,OO CSS 只是某些人采用的一种方法,因为它看起来更合乎逻辑。如果您正在编写将由开发人员维护的 CSS,那么这种方法将非常适合。这真的取决于你如何编写你的 CSS 和你自己的个人风格......
就我个人而言,我并不关心人们如何编写他们的 CSS - 如果需要我来维护它,无论如何,Firebug 都会让这项工作变得微不足道。
【讨论】:
我已经说过这句话年了。
CSS 选择器基于实例 ID 和类。它甚至支持多重继承。这能有多明显?
从对象角度考虑 CSS 的美妙之处在于,开始“投射”标记元素变得非常简单。需要那个 div 突然变成 INotRenderedAnymore 吗?让 JS 扩展它的类属性来匹配.removed,不要乱用样式属性。
显然这是一个相当陈词滥调的例子,但好处应该是显而易见的——尤其是在 JS 操作的上下文中。您可以将 JS 与其必须修改的实际样式解耦,这既是维护和抽象的好处,也有附带好处,例如不直接设置非常高特异性的样式(CSS 无法覆盖)。
【讨论】:
我想说,对于 CSS 中已经存在的东西,它更像是一个吸引人的流行语。当然,在我们开始谈论什么是 OO 和什么不是以及 CSS 如何面向对象之前,我们必须先定义它实际上是什么——这是其他人之前一直在努力解决的问题,并且受到了激烈的争论。但是如果我们假设the basic principles of OO are:
我们可以说,级联样式表在某种程度上是面向对象的,因为它们允许定义类、创建实例/对象(通过将类分配给元素)、类的继承(甚至多重继承)、抽象(例如,通过为普通元素定义样式)和多态性(通过为不同元素定义相同的类名)。当然,由于 CSS 的静态特性,方法/消息传递是不可能的。
所以总的来说,我会说它是一种以面向对象的方式开发 CSS 的有效方法,但我不会真正将其称为面向对象的 CSS,因为至少对我而言,它是 CSS 固有的东西。这有点像说“我正在做面向对象的 Java...”
【讨论】:
我认为将其称为“面向对象的 CSS”的流行语实际上削弱了它的实用性和该概念的广泛采用。
当我阅读它时,我认为它是 OO 的说法实际上减慢了我对它的真正含义的理解。
知道“面向对象”在编程中的含义的人会怀疑,因为它不是真的 OO,是吗?这只是尝试将一些OO原则应用于CSS以提高其效率。另一方面,如果不是程序员,大多数客户端开发人员根本不会理解这个概念,因此他们只会感到困惑或尴尬。
所以,伟大的概念,需要重新命名。最大的 CSS!给 CSS 供电! CSS重生! CSS平方! CSS 总理!类似的东西。
【讨论】:
CSS 在很多方面都类似于 OO 语言:写成
p { color: red }
p span { color: blue }
你基本上拥有继承权。下面是一个更复杂的例子,让 terrier 扩展 dog 扩展动物类:
.animal { font-weight:bold; color: blue; }
.dog:before, .terrier:before { content: "GRRR"; }
.animal, .dog, .terrier { color: brown }
现在您可以以 OO 方式使用类动物、狗和梗犬。
重要的是要记住,CSS 非常适合解决它的问题:以透明的方式指定元素的样式。使用更多面向对象的概念会更好吗?我不知道。假设有人说:如果 CSS 文件看起来像这样会更简单:
@class dog @derives_from animal /* the syntax i just invented */
@class terrier @derives_from dog
.animal { font-weight:bold; color: blue; }
.dog:before { content: "GRRR"; }
.terrier { color: brown }
这看起来确实更简单,但更简单的解决方案是删除 @class 的东西,同时将 'dog' 添加到任何 'terrier' 和 'animal' 到任何 'dog' 服务器端(简单的替换语句)或使用 javascript。
CSS 最棒的地方在于它很简单,而且很容易回退,这意味着浏览器不需要解释它们不理解的 CSS,而且一切正常。由于您必须打破这种与主要新 CSS 结构的向后兼容性,我认为这会使面向对象的 CSS 成为一个流行语。
【讨论】:
这么多年后为后代写下这个答案。上面所有的答案显然从未听过关于面向对象的 CSS 的严肃讨论。当 OP 询问它是否是一个流行词时,这应该表明该表达式指的是一个值得讨论的主题(比“我们所说的面向对象是什么意思?”)。
我相信面向对象的 CSS 是雅虎前端技术布道者 Nicole Sullivan 创造的一个术语,她曾为 Facebook 提供咨询,将他们的演示前端代码重构为更精简、更易于管理的东西,并且可以扩展和修改随着时间的推移很容易。术语“面向对象”不是指 CSS 本身的本质(本身),而是指一种编写 CSS 和受影响的标记的方法,这种方法有助于简洁和可扩展。
OO CSS 的一些示例原则包括:
OOCSS 的最终目标是 DRY。当您实际上是在创建类似事物的变体时,您不应该编写数千行 CSS。
Nicole 就这个主题发表了一些 good talks 的文章——她还写了几篇文章扩展了一些 useful techniques 以供雇用和 bad practices 避免使用。
'OOCSS' 也是她编写的framework 的名称,它为可扩展的 CSS 布局提供了一些样板代码。这个框架如何以及为什么这么好(grids module 是我几乎在任何地方都使用的东西)从代码本身并不是完全不言而喻的,阅读她关于背后想法的博客文章肯定有助于更好地利用它和一般的 CSS。
【讨论】:
“面向对象的 CSS”一词用词不当。
“面向对象的 CSS”实际上只是一种如何充分利用 CSS 的设计模式,与 Jonathan Snooks 所称的 SMACSS 基本相同。
无论您将其称为 OOCSS 还是 SMACSS,该方法的关键在于您创建通用 UI 元素,例如 nav abstraction。然后可以通过向元素和/或容器元素添加额外的类来增强这些 UI 元素的特定功能。或者,作为替代方案,您可以使用元素的 ID 或语义类添加自己的自定义 CSS 规则。
Cascade Framework 是基于这种方法的全新 CSS 框架。它只需占用很小的空间即可为您提供最佳性能、最佳灵活性和最佳模块化。
【讨论】:
我一直让 OOCSS 和 B.E.M. 都感到尴尬。命名约定很长一段时间,并且永远不会回头。对于那些声称这只是一个“流行的流行语”或“CSS 已经可以做到这一点”的人,不了解使用这两种方法编写 css 的潜力。
让我们看看最简单的对象,一个带有链接的列表。它有许多不同的口味:
菜单
工具栏
标签
面板(引导)
在 OOCSS 中,我们找到每个属性的共同属性并创建一个基础对象。我通常称之为导航。
/* Nav
=================================================*/
/* B
---------------------------------------------*/
.nav
{
margin-left: 0;
padding-left: 0;
list-style: none;
}
/* E
---------------------------------------------*/
.nav__item
{
float: left;
}
.nav__link
{
display: block;
color: inherit;
text-decoration: none;
}
/* M
---------------------------------------------*/
.nav--right
{
float: right;
}
.nav--stack .nav__item
{
float: none;
}
你会注意到一些事情:
Nav 是应用于块元素的基础对象
子元素以 nav_ 为前缀
修饰符以 nav-- 为前缀
修饰符是一种改变行为的选项。例如 --right 浮动导航。
一旦我拥有了我的基础对象,我就会创建将改变对象外观的皮肤。这将把它变成工具栏、选项卡等。微软在他们的手机上有 Pivot 选项卡。现在创建fpr的皮肤更容易了。
/* Nav
=================================================*/
/* E
---------------------------------------------*/
.pivot .nav__item
{
margin-left: 24px;
color: #aaa;
font-size: 36px;
}
.pivot .nav__item--active, .pivot .nav__item:hover
{
color: #000;
}
要使用这个对象和皮肤,你会写
<ul class="pivot nav">
<li class="nav__item">
<a class="nav__link"> Item 1 </a>
</li>
<li class="nav__item">
<a class="nav__link"> Item 2 </a>
</li>
</ul>
因为它的位置独立,你也可以写成
<nav class="pivot nav">
<div class="nav__item">
<a class="nav__link"> Item 1 </a>
</li>
<div class="nav__item">
<a class="nav__link"> Item 2 </a>
</div>
</nav>
最终,您将容器与皮肤分离。我建议从 Nicole Sullivans 媒体对象开始。查看 Twiter Bootstrap 和 Inuit.css 以获得更多灵感。
【讨论】:
#annoying_section_2chng .nav > <some element>
我相信这没什么。
OOCSS 面向对象的层叠样式表
它减少了一遍又一遍地重复的代码,您可以为 foocontainer 设置一个全局 css 并在任何地方重复使用,并为 header body 和 footer 自定义样式。
<div class="foocontainer header"> Your header </div> <!-- two classes -->
<div class="foocontainer body"> Your body </div> <!-- two classes -->
<div class="foocontainer footer> Some footer </div> <!-- two classes -->
BEM Block--Element__Modifier
它使代码易读但难写,您可以轻松识别孩子和他们的父母。
<div class="foocontainer--header"> Your header </div> <!-- one class -->
<div class="foocontainer--body"> Your body </div> <!-- one class -->
<div class="foocontainer--footer> Some footer </div> <!-- one class -->
【讨论】: