css可维护方案:OOCSS VS BEM

做为一个前端,你敢说本身懂css,敢自信的说本身精通css吗?css编写很简单,可是初期的结构设计,后期的维护是一项很是消耗脑力的事情。css

在这里,抛出两个名词:oocss和BEM.html

什么是oocss?

还没了解过的能够看这篇文章 OOCSS vs. OOSCSS
相信你们都用过bootstrap,bootstrap就是典型的面向对象css,即oocss.前端

面向对象的CSS是一种容易重用的一种CSS规则,这里关键的一点就是如何在页面中识别,建立和模块化可重用的对象,并在页面中任何须要的地方重用,并扩展其附加功能。因此个人理解是,oocss是一种可重用,样式分离,耦合度低的css.bootstrap

缺点:

  1. OOCSS适合真正的大型网站开发,由于大型网站用到的可重用性组件特别的多,若是运用在小型项目中可能见不到什么成效。因此用不用OOCSS应该根据你的项目来决定。
  2. 若是没用巧妙的使用,建立组件可能对于你来讲是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定仍是个维护的噩梦。
  3. 最好给每个组件备写一份说明文档,有助于调用与维护
  4. 建立了数千行CSS,但有可能这些CSS永远不会被使用。好比Twitter Bootstrap
  5. 样式(CSS)和结构(HTML)藕合太紧

优势:

  1. 强调重用,减小CSS代码
  2. 选择器简洁
  3. 可扩展类
  4. 强调风格与内容分离
  5. 强调内容与容器分离
  6. 具备清洁的HTML标记,有语义的类名,逻辑性强的层次关系
  7. 语义标记,有助于SEO
  8. 可扩展的标记和CSS样式,有更多的组件能够放到库中,而不影响其余的组件

举个例子

//css写法
.title-1{
    border-bottom:1px solid #ccc;
    font-size:16px;
    font-weight:bold;
    color:#333;
}

//OOCSS写法
.bb-c{
    border-bottom:1px solid #ccc;
}   
.f16{
    font-size:16px;
}
.bold{
    font-weight:bold;
}
.c333{
    color:#333;
}

//html
<div class="f16 bold c333 bb-c">标题</div>复制代码

然而,你会以为这给html添加了太多的负担,因此我更推荐使用oosass。 segmentfault

oosass是可伸缩,面向对象的CSS,其实它就是OOCSS的一个变异体,进化体。 sass

oosass的特色:

  1. 没有CSS,只有Sass
  2. 经过%placholder来声明视觉对象
  3. 能够经过mixin建立可重复的CSS
  4. 语义化的类名在DOM中声明,而视觉化类名在Sass中声明,不然不可能使用CSS构建UI结构和框架
  5. 经过Sass来扩展类,而不是经过DOM来扩展类

举个例子,上述代码能够变为:app

%bb-c{
    border-bottom:1px solid #ccc;
}   
%f16{
    font-size:16px;
}
%bold{
    font-weight:bold;
}
%c333{
    color:#333;
}
%c999{
    color:#999;
}
.title-1{
    @extend %bb-c;
    @extend %f16;
    @extend %bold;
    @extend %c333;
}

//假设有类title-2
.title-2{
    @extend %f16;
    @extend %c999;
}复制代码

则生成的代码为:框架

.title-10 {
  border-bottom: 1px solid #ccc; 
}

.title-10, 
.title-20 {
  font-size: 16px; 
}

.title-10 {
  font-weight: bold; 
}

.title-10 {
  color: #333; 
}

.title-20 {
  color: #999;
}复制代码

值得注意的是,在动手写oosass以前,必定要动脑好好想一想怎么构建本身的原子类库,由于只要你的原子类足够好,你后面的组件和页面只须要extend原子类,代码基本不会有增长。原子库的构建思路以下:模块化

/**
 * 原子类 - 文本控制
 */

%tl {
    text-align: left;
}

%tr {
    text-align: right;
}

%tc {
    text-align: center;
}

/**
 * 原子类 - 字体大小控制
 */
%f12 {
    font-size: 12px;
}

%f14 {
    font-size: 14px;
}

%f16 {
    font-size: 16px;
}

%f18 {
    font-size: 18px;
}

/**
 * 原子类 - 定位
 */

%fl {
    float: left;
}

%fr {
    float: right;
}

%pr {
    position: relative;
}
%pa {
    position: absolute;
}复制代码

固然,若是你须要用到覆盖的时候,就没法@extend了,由于原子类在最上层,优先级不够。布局

什么是BEM?

BEM表明块(Block),元素(Element),修饰符(Modifier)。

Block 是页面中独立存在的区块,能够在不一样场合下被重用。每一个页面均可以看作是多个Block组成。

Element 是构成Block的元素,只有在对应Block内部才具备意义,是依赖于Block的存在。

Modifier 是描述Block或Element的属性或状态。同一Block或Element能够有多个Modifier。

不少人对BEM的第一印象是:又长又丑,一点都不漂亮!

运用BEM思想的框架,网站:

饿了么的框架elementUI就是BEM的一种,你也能够研究网站company.yandex.ru/

若是你没接触过BEM,能够查看文章:BEM的定义

他的命名规范

下划线和横线

component-name 
component-name--modifier-name 
component-name__sub-object 
component-name__sub-object--modifier-nam复制代码

驼峰

org-ComponentName 
org-ComponentName--modifiername 
org-ComponentName-subObject 
org-ComponentName-subObject--modifiername复制代码

由于时常存在块嵌套另外一个块的问题,可使用前缀来区分

p-页面(Page) (应用于body元素的类),对可维护性不是那么重要的静态页面十分有用 —应该避免嵌套使用 (例: p-Homepage);
l-布局(Layout), 好比列(columning),包裹(wrappers) 和容器(containers)等等(例: l-Masthead, l-Footer);
c-组件(components )(例: c-Dropdown, c-Button…);
u-公共类(Utility classes) — 不会发生改变, 在代码的任何地方都不能重载。(例: u-textCenter, u-clearfix…);
js-JavaScript钩子:永远不该该出如今CSS中。
g-JavaScript钩子:全局js类,永远不该该出如今CSS中复制代码

解决嵌套的思路能够参考文章:关于BEM中常见的十个问题以及如何避免

最佳实践:

<div class="c-card">
    <div class="c-card__header"> <h2 class="c-card__title">Title text here</h3> </div> 
    <div class="c-card__body">
        <p>I would like to buy:</p> <!-- Much nicer - a layout module --> 
        <ul class="l-list"> <li class="l-list__item"> <!-- A reusable nested component --> <div class="c-checkbox"> <input id="option_1" type="checkbox" name="checkbox" class="c-checkbox__input"> <label for="option_1" class="c-checkbox__label">Apples</label> </div> </li> <li class="l-list__item"> <div class="c-checkbox"> <input id="option_2" type="checkbox" name="checkbox" class="c-checkbox__input"> <label for="option_2" class="c-checkbox__label">Pears</label> </div> </li> </ul> <!-- .l-list --> </div> <!-- .c-card__body --> </div> <!-- .c-card -->复制代码

优势

  1. 解决了命名空间的问题
  2. 多人协做时,只要有文档清楚标注规则,后来人能够很轻易的读懂,接手
  3. 更易于维护

缺点

  1. 容易写的又长又丑
  2. 代码量比较多,没这么简洁
  3. 须要完善的说明文档和规则

个人理解

我的以为,若是从组件来讲,使用BEM很不错,定制化样式就用oosass,二者结合使用,纯属我的观点,欢迎提出你的意见及实践。毕竟我只是纸上谈兵。

参考文档

www.w3cplus.com/preprocesso…
www.w3cplus.com/css/oocss-c…
segmentfault.com/a/119000000…
www.w3cplus.com/css/fifty-s…

相关文章
相关标签/搜索