面向对象的CSS很不错,但是让非语义化的词标识你的类是很不明智的。这些类散布在你的HTML里面等着去做调整,会变得很没意思。但是如果你把OOCSS和Sass结合就让未经渲染的模块化CSS和难以维护的HTML变得两全其美了。
OOCSS导致HTML难以维护
首先是简单的声明,其次是一大把可能吓坏你的非语义化的词语。这里,实际上我不关心它们被非语义化,我关心的是它们可维护的意义。非语义化的类不需要描叙成那些可能会变成的组件名。
用单纯的CSS建模的唯一方式是定义非语义化的类,然后你把这些类应用到HTML元素中。这就是接触模型的OOCSS方式。但是,问题来了:
1、我不想每次改变样式都得带上HTML。从一开始,事情就在一直变。 2、我甚至不想接触那些我要增加类的那些DOM元素.如果你正在使用Javascript组件渲染页面元素,那你就不能给组件里面的元素增加类(除非你在做一些无法描叙的事情)。
除了那些不可维护的HTML,OOCSS其他方面还是完全可行的。抽象重复的代码到模块的唯一方法是让CSS在大型项目中变得可维护。那怎样我们才可以做到百利而无一害呢?
解放OOSass!
OOCSS和Sass的结合给了你超强力量。Sass上的@extent指令让你从另外的选择器上继承样式而不需要复制所有的代码,像一个代码块(@mixin)。如果你内嵌他们或和内嵌选择器一起使用他们,即便那些让人感觉亲切的@extent调用也能导致代码臃肿。 幸运的是Sass3.2增加了一个叫占位符(Placeholder)的新特性。占位符是那种除非他们被扩展否则什么也不输出的选择器。下面是个占位符的例子:
2 |
border-top : 1px solid black |
它会生成下面这样的CSS:
3 |
border-top : 1px solid black |
占位符不会导致像混合类型或@extent调用有的那种代码臃肿的问题。这使得占位符完美适用在那些非语义化CSS模块。我叫这些模块为“模式”。他们是那种小段的样式,可以通过你的样式进行混合搭配。
真实样例展示
采用OOCSS黄金产物作为例子: .media模块。你可能想应用.media模式到你组件的一个分支: .status 、.profile等等。 情况就是这样的,你不想再HTML里面重复.media类,但你想把它的样式复制到.status和.profile类上。使用占位符很容易就可以实现。 下面是我们给出的%media模式。
现在你不需要复制media类的代码,你只要扩展 %media 模式到你任何想要使用的地方就可以了。
3 |
// Status-specific styles here... |
7 |
// Profile-specific styles here... | 这意味着在HTML里面你只需要增加一些语义化的类:.status和.profile——这些你不用在意类型因为你只在<article>元素中用到它了。 这东西很灵活。如果你要改变状态显示方式让.media模式不再应用只要移除@extend调用就可以了,而不用删除.media类。 眼尖的话应该注意到了 这里我使用了稍稍修改过的.media模式版本。这是因为当使用Javascript组件时不能使用DOM...
OOSass让给Javascript组件定义样式变得容易。
OOCSS的最大问题是它已经假设你对DOM和增加的类完全控制。那是不可能的。当你渲染Javascript组件或其他一些操作时,你只可能拿到组件最顶端的元素。
如果你要将.user-dropdown类应用到下拉视图上,你可以扩展一个.media类到.user-dropdown类上。但是要增加类到下拉菜单的按钮上或它的任一餐单项上是不可能的,因为你不能控制组件里面的DOM元素。 不过有了Sass占位符,这不是问题:
2 |
// Normal styles for every dropdown... |
5 |
// Extra styles for user-specific dropdowns... |
要是你想用纯粹CSS类你就不得不做些粗俗的事情:进入组件里面破坏它们的分装,或使用一些可怕的基于字符串的类名API。使用Sass模式你很容易就增加了DOM元素而不需要直接控制它。
好了,看了例子吧。 我喜欢读别人的CSS模式,就好像已经分享了我自己的一些代码。下面是我在整个Segment.io上使用到得一些模式。
Lip 这是一个苹果风格的分隔符,在它下面创建了一个在内容上面的lip类(注意我也用了%reversed-lip来控制在向反方向的lip)
05 |
background : url ( '/public/images/patterns/lip/lip.png' ) no-repeat |
06 |
background- size : 100% 100% |
10 |
background-image : url ( '/public/images/patterns/lip/reversed-lip.png' ) |
Valley 这里只是增加两个lip到元素的顶部和底部,让它感觉像是嵌入进去的。
Plane 一个非常简单的圆角盒子。这是在Segment.io上所有色块的基础。
02 |
box-shadow: 0 2px 5px rgba($ black , . 1 ) |
03 |
border-radius: $border-radius- medium |
07 |
background-color : $ white |
11 |
background-color : $off- white |
Seam 你知道那些人们通过把黑线和白线放在一起做成半透明的边框不?我叫它seam。
5 |
border-top : 1px solid rgba($ black , . 12 ) |
6 |
border-bottom : 1px solid rgba($ white , . 15 ) |
Well 和valley差不多,它只是页面的一块洼地,对于像<code>这样的例子。(它和这个博客的代码例子很相似。)
02 |
box-shadow: inset 0 1px 5px rgba($ black , . 14 ) |
03 |
border-radius: $border-radius- medium |
07 |
background-color : $off- white |
11 |
background-color : $light- gray |
准备开始吧
希望上面这些能给你一些启示——什么事模式能做的及怎样在你的CSS组件中使用他们。它们无处不在。
它们应该只做一件事情并把它们做好。Harry Roberts提到应该给它们一个模糊的非语义化的名称。这样促使你把它们抽象出来,以便在任何地方使用。你还可以每次都在最前面建一些模式,就像我在valley的例子中做的一样。
如果你自己也拥有一些类似的模式那就更好了。
原文链接/OSCHINA翻译
|