基于 Sass 使用面向对象 CSS

2,652 阅读4分钟
原文链接: www.w3ctrain.com

本文为全文翻译,原文链接,请看文章底部。

Nicole Sullivan 在08年的 Web Directions North上第一次提出了OOCSS这个词,如今已成为组织主流的CSS模块化系统之一。

OOCSS与其他CSS方法论(比如SMACSSBEM)不同。它们的主要目的是通过把css风格转成可重用的模块化代码,以便从结构中分离出内容。事实上,我会混用SMACSS和OOCSS。

今天,我将简要介绍Object-Oriented CSS的基本原则,然后使用SASS来让代码更高效。

什么是对象

对象是重复的可见模型,可以抽象为一小段独立的HTML,CSS也可以是JavaScript - Nicole Sullivan

创建CSS对象的时候我们的首要任务是抽象。代码解耦和组织最好的方式是什么?Nicole Sullivan定义了以下两个条原则:

  • 分离结构和样式:你应该保持结构和定位放在基本对象中,可见因素(比如background,border)放在在扩展类中。这样你就不需要重写可见属性。
  • 分离容器和内容:永远不要在HTML的结构中混合CSS,换句话说,不要在你的样式表中使用tags,IDs。相反,尝试创建类,和应用类。并且保持嵌套类层次尽量得少。

DEMO

应用原则是非常困难的,我们来看看例子:

/* The bad way */
.box-1 {
  border: 1px solid #ccc;
  width: 200px;
  height: 200px;
  border-radius: 10px;
}
.box-2 {
  border: 1px solid #ccc;
  width: 120px;
  height: 120px
  border-radius: 10px;
}

如果你仔细看,你会注意到,我们重复了部分可视代码,并且这部分代码可能会在其他地方用到。我们可以提取border-radius和border属性。

/* The good way */
.box-1 {
  width: 200px;
  height: 200px;
}
.box-2 {
  width: 120px;
  height: 120px;
}
.box-border{
  border: 1px solid #CCC;
  border-radius: 10px;
}

现在我们可以应用这些类到HTML上了,通过组合来继承对象。

Lorem ipsum
Lorem ipsum

无语义化、维护

你不应该把重点放在代码会变得无语义化,我关注的是如何维护。

纯CSS定义对象的唯一方式就是定义无语意化的类,然而这会带来一些问题:

  • 基本上每次我们修改样式都必须修改HTML
  • 访问一些DOM元素不太安全

除了难以维护HTML,OOCSS几乎完美。使用抽象类,我们的CSS代码是可扩展并且容易维护的。

然而有更好的方式吗?

Sass大法

我相信你肯定听过Sass的@extend命令。所以,感谢占位符可以让我们在Sass中实现继承,创建语义化类,解决我们在HTML中的问题。

我们使用占位符作为对象,然后定义类时只通过@extend来继承他们。结果就是我们不需要再每次写重复的代码。

/* The bad way */
a.twitter {
  min-width: 100px;
  padding: 1em;
  border-radius: 1em;
  background: #55acee
  color: #fff;
}
span.facebook {
  min-width: 100px;
  padding: 1em;
  border-radius: 1em;
  background: #3b5998;
  color: #fff;
}

应用@extend来混合基本对象,于是我们获得了非常容易维护的object-oriented CSS代码,并且我们不需要再每次修改HTML了!!!

/* The best way */
%button {
  min-width: 100px;
  padding: 1em;
  border-radius: 1em;
}
%twitter-background {
  color: #fff;
  background: #55acee;
}
%facebook-background {
  color: #fff;
  background: #3b5998;
}

.btn {
  &--twitter {
    @extend %button;
    @extend %twitter-background;
  }
  &--facebook {
    @extend %button;
    @extend %facebook-background;
  }
}

在HTML中我们这样使用:



非常漂亮的语义化,对吧?Sass解决了我们的问题。记住:如果你想获得语义化,容易维护的HTMl,那么在Sass中继承和组合无语义代码。

我喜欢称之为OOSass,因为它组合了Sass和OOCSS的特性。当然,你不需要非得这么用。如果你不在乎无语意HTML代码,那么你可以使用OOCSS没有问题。你又是如何组织的CSS代码的呢?

译文到此为止

@extend 大法非常好用,但使用的时候需要慎重考虑,比如,定义了几个不相关的类:

%brand-font {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

...

h1 {
    @extend %brand-font;
    font-size: 2em;
}

...

.btn {
    @extend %brand-font;
    display: inline-block;
    padding: 1em;
}

...

.promo {
    @extend %brand-font;
    background-color: #BADA55;
    color: #fff;
}

...

.footer-message {
    @extend %brand-font;
    font-size: 0.75em;
}

结果如我们所愿。

h1, .btn, .promo, .footer-message {
    font-family: webfont, sans-serif;
    font-weight: 700;
}

...

h1 {
    font-size: 2em;
}

...

.btn {
    display: inline-block;
    padding: 1em;
}

...

.promo {
    background-color: #BADA55;
    color: #fff;
}

...

.footer-message {
    font-size: 0.75em;
}

然而,现在我们无意中把很多不相关的类绑定到了一块,强制给了它们关系[/捂脸]。如果很多类都extend一下,再多级嵌套,那么当你打开浏览器调试工具的时候,就能看到大量不想关的元素,出现在Element模块,强迫症的你肯定不能容忍。这种情况下就建议使用@mixin来实现继承

.product .single_add_to_cart_button, .cart .button, input.checkout-button.alt.button, .shipping-calculator-form .button, .multistep_step .button, #place_order.button, .single-product .single_add_to_cart_button.button.alt, .woocommerce a.button, .woocommerce button.button, .woocommerce input.button, .woocommerce #respond input#submit, .woocommerce #content input.button, .woocommerce-page a.button, .woocommerce-page button.button, .woocommerce-page input.button, .woocommerce-page #respond input#submit, .woocommerce-page #content input.button {
  background-color: #605f5e;
}

推荐阅读

本文根据@Jaime Caballero所译,整篇译文带有我们自己的理解和意思,如果有译得不好的地方或者不对之处,还请大家指点。英文出处:Using Object-Oriented CSS with Sass

如需转载,请注明出处:w3ctrain.com/2015/12/13/…