好程序员web前端分享值得参考的css理论:OOCSS、SMACSS与BEM
最近在The Sass Way里看到了Modular CSS typography一文,发现文章在开头部分就提到了OOCSS、 SMACSS、 BEM、这3个词。“若是还不知道这些是什么,请先不要继续看下去”,联想到做者这样友好(gāo lěng)的提醒,做为围观群众,天然要有所回应。因此,本文在这里分别介绍它们。javascript
OOCSS、SMACSS及BEM都是有关css的方法论(准确地说,其中BEM应该是一个完整的前端开发理论,不只限于css),可做为实现优秀css架构(css architecture)的指南。css
css易于理解,但应用和维护并不简单。在各类开发情景下,css均可能成为一个问题点。所以,咱们编写和组织css应认真、用心。html
OOCSS前端
OOCSS (Object Oriented CSS),字面意思是面向对象的CSS,是由Nicole Sullivan提出的css理论,其主要的两个原则是:java
Separate structure and skin(分离结构和主题) Separate container and content(分离容器和内容)程序员
用一个例子来讲明。请看下面这样的图文排列:web
本做的主角,帝国北部地方贵族施瓦泽男爵的养子,也是托尔兹士官学校特科班“Ⅶ组”的成员。sass
.media{
1.<p><font size="3"> padding: 10px;</font></p>
2.<p><font size="3"> }</font></p>
3.<p><font size="3"> .media:after{</font></p>
4.<p><font size="3"> display: table;</font></p>
5.<p><font size="3"> clear: both;</font></p>
6.<p><font size="3"> content: " ";</font></p>
7.<p><font size="3"> }</font></p>
8.<p><font size="3"> .media-image-container{</font></p>
9.<p><font size="3"> float: left;</font></p>
10.<p><font size="3"> margin-right: 10px;</font></p>
11.<p><font size="3"> }</font></p>
12.<p><font size="3"> .media-image{</font></p>
13.<p><font size="3"> display: block;</font></p>
14.<p><font size="3"> }</font></p>
15.<p><font size="3"> .media-body{</font></p>
16.<p><font size="3"> overflow: hidden;</font></p>
17.<p><font size="3"> }</font></p>
18.<p><font size="3"> .media-shadow{</font></p>
19.<p><font size="3"> box-shadow: 1px 1px 3px rgba(0, 0, 0, .5);</font></p>
20.<p><font size="3"> }</font></p>架构
上面这段代码用media表示了这种图文排列的页面元素。若是把构成它的html、css及javascript(若是有)看作一个总体,那就至关于这是一个元件,或者说对象(object)。它能够在站点的任何地方被重用。
这样是如何体现OOCSS的两个原则的呢?
Separate structure and skin
分离结构和主题是在于将一些视觉样式效果(例如background、color)做为单独的“主题”来应用。在上面的例子中的阴影效果,没有被直接写在media的样式规则内,而是被单独写在了一个名为media-shadow的class中。所以,它成为了可选择、可拆分的主题。若是不须要对应主题,什么也不要加,若是须要,加上对应的class,就是这样的思路。
Separate container and content
分离容器和内容要求使页面元素不依赖于其所处位置。在上面的例子中,css的选择符都很短,无继承选择符(例如.header .media { }),因此,这个图文排列的元件,能够在任何地方使用,且会有一致的外观。
若是须要在特定的地方让这个元件看起来不同一些,继续为这个元件增长class,将“不同的部分”做为可配置的选项。元件的外观仍不依赖其所处位置。less
操做指南
能够看出,OOCSS风格的css能够描述为两点:
增长class 不使用继承选择符
OOCSS追求元件的复用,其class命名比较抽象,通常不体现具体内容。
SMACSS
SMACSS (Scalable & Modular Architecture for CSS),是由Jonathan Snook提出的css理论。其主要原则有3条:
Categorizing CSS Rules(为css分类) Naming Rules(命名规则) Minimizing the Depth of Applicability(最小化适配深度)
这些原则分别是什么意思呢?
Categorizing CSS Rules
这一点是SMACSS的核心。SMACSS认为css有5个类别,分别是:
Base Layout(Major Components) Module(Minor Components) State Theme
Base Rules, 基础样式,描述的是任何场合下,页面元素的默认外观。它的定义不会用到class和ID。css reset也属于此类。
Layout Rules, 布局样式。它和后面的Module Rules一同,描述的是页面中的各种具体元素。元素是有层次级别之分的,Layout Rules属于较高的一层,它能够做为层级较低的Module Rules元素的容器。左右分栏、栅格系统等都属于布局样式。
Module Rules, 模块样式。它能够是一个产品列表,一个导航条。通常来讲,Module Rules定义的元素放置于前面说的Layout Rules元素以内。模块是独立的,能够在各类场合重用。
State Rules, 状态样式,描述的是任一元素在特定状态下的外观。例如,一个消息框可能有success和error两种状态,导航条中的任一项均可能有current状态。
继续OOCSS中的例子,下面新增的让元素不显示的is-hidden就属于State Rules:
...
1.<p><font size="3"> 复制代码</font></p>
2.<p><font size="3"> .is-hidden{</font></p>
3.<p><font size="3"> display: none;</font></p>
4.<p><font size="3"> }</font></p>
Theme Rules, 主题样式,描述了页面主题外观,通常是指颜色、背景图。Theme Rules能够修改前面4个类别的样式,且应和前面4个类别分离开来(便于切换,也就是“换肤”)。SMACSS的Theme Rules不要求使用单独的class命名,也就是说,你能够在Module Rules中定义.mod { }而后在Theme Rules中也用.mod { }来定义须要修改的部分。
Naming Rules
Naming Rules是说在想class等的命名时,考虑用命名体现样式对应的类别。
按照前面5种的划分,Layout Rules用l-或layout-这样的前缀,例如:.l-header、.l-sidebar。
Module Rules用模块自己的命名,例如图文排列的.media、.media-image。
State Rules用is-前缀,例如:.is-active、.is-hidden。
Theme Rules若是做为单独class,用theme-前缀,例如.theme-a-background、.theme-a-shadow。
Base Rules不会用到class和ID,是以标签选择符为主的样式,例如p、a,无需命名。
命名规则不须要严格遵照,能够根据实际状况和自身喜爱作其余的约定。记录本身的约定(写文档),而后遵照,就是可行的。
Minimizing the Depth of Applicability
字面翻译是最小化适配深度。经过一个简单的描述来讲明:
/ depth 1 /
1.<p><font size="3"> .sidebar ul h3 { }</font></p>
2.<p><font size="3"> / depth 2 /</font></p>
3.<p><font size="3"> .sub-title { }</font></p>
上下两端css的区别在于html和css的耦合度。能够想到,因为上面的样式规则使用了继承选择符,所以对于html的结构实际是有必定依赖的。若是把h3元素搬到另外一个位置,就有可能再也不具备这些样式。对应的,下面的样式规则只有一个选择符,所以不依赖于特定html结构,只要为元素添加class,就能够得到对应样式。
固然,继承选择符是有用的,它能够减小因相同命名引起的样式冲突(常发生于多人协做开发)。可是,咱们不该过分使用,在不形成样式冲突的容许范围以内,尽量使用短的、不限定html结构的选择符。这就是SMACSS的最小化适配深度的意义。
看起来,这一点和OOCSS的分离容器和内容的原则很是类似。
主要目标
SMACSS着力于实现两个主要目标:
更语义化的html和css 下降对特定html结构的依赖 BEM
BEM,即Block, Element, Modifier,是由Yandex(俄罗斯最著名的互联网企业)的开发团队提出的前端开发理论。BEM经过Block、Element、Modifier来描述页面。
Block是页面中独立存在的区块,能够在不一样场合下被重用。每一个页面均可以看作是多个Block组成。
Element是构成Block的元素,只有在对应Block内部才具备意义,是依赖于Block的存在。
Modifier是描述Block或Element的属性或状态。同一Block或Element能够有多个Modifier。
这三部分结合在一块儿,能够体如今class命名上,从而为开发者提供更友好、更有意义的css组织方式。其形式是:
.block { }
1.<p><font size="3"> .block_modifier { }</font></p>
2.<p><font size="3"> .block__element { }</font></p>
3.<p><font size="3"> .block__element_modifier { }</font></p>
再回到前面OOCSS的那个图文排列的例子,对应用BEM的写法的话就是:
本做的主角,帝国北部地方贵族施瓦泽男爵的养子,也是托尔兹士官学校特科班“Ⅶ组”的成员。
这样的写法的好处是,在class命名上以约定的形式携带了更多有用信息。在多人合做的时候,新接手这个项目的人,也能够很容易从class命名上分辨出来,哪些部分是Block,哪些是对应的Element,哪些是Modifier,并进一步推断出哪部分html能够独立使用。
BEM是完整的前端开发理论,这里只是提到了它采用的css的class命名规则。能够看出,BEM的命名规则可使代码更易于维护。
这些理论真的能够应用吗?
是的,并且有用。可是,请不要过于乐观,任一种理论都只是对解决css编写、维护问题的一种尝试,及其经验总结。就实际具体的项目来讲,你可能仍然会遇到困惑。这些理论最重要的是提供了一种思路(即便它们也提供开发模式的代码库),你可能不直接应用它们,但应该经过它们认识到,在写代码以前,须要多一些思考。
不直接编写css而是采用less、sass等预编译器,也一样须要合理的代码编写和组织方式,由于能够从编译后获得的css来分析,因此原则是相通的。
结语 在整理写文本以前,我只初步了解过OOCSS,而对另外2个尚未印象...(嗯,其实很正常) 本文的3个理论各有各的风格,没有孰优孰劣之说,都是在编写css时值得参考的内容。若是能够,很是推荐本身根据这些理论背后的意图,想一个适合本身的方法。