CSS 架构的那些事儿

545 阅读8分钟

常见的css 命名规范有如下几种:

  • BEM  
  • SUIT
  • OOCSS
  • SMACSS
  • ACSS
  • ITCSS

BEM

最流行的命名规则之一就是BEM(block:块,Element:元素,Modifier:修饰符)。通过给每个元素添加它的父级block模块作为前缀,使得目标的安全性变得更加简单了。BEM还有助于消除页面和body类对嵌套或者附加样式依赖。 规则:下划线(__)被用来区分元素,而用连字符(--)是用来修饰元素的。下面是一个现实世界的例子...

// 创建的写法
.block {} 
.block__element {} 
.block--modifier {}

// 例子

.product-details {} 
.product-details__price {} 
.product-details__price--sale {}

// 例子
.product-details {} 
.product-details__title {} 
.product-details__title--small {}

优点:

  • 结构清晰,目标安全性很高。
  • BEM还有助于消除页面和body类对嵌套或者附加样式依赖。

缺点:

  • 在修饰部分中添加多种用途的样式类。比如说:大的,小的,绿的,红的等醒目的修饰符。这种修饰符存在变化的可能性。
  • 当一个设计改变的时候常常会导致矛盾的CSS。

ACSS

考虑如何设计一个系统的接口。原子(Atoms)是创建一个区块的最基本的特质,比如说表单按钮。分子(Molecules)是很多个原子(Atoms)的组合,比如说一个表单中包括了一个标签,输入框和按钮。生物(Organisms)是众多分子(Molecules)的组合物,比如一个网站的顶部区域,他包括了网站的标题、导航等。而模板(Templates)又是众多生物(Organisms)的结合体。比如一个网站页面的布局。而最后的页面就是特殊的模板。 image.png 举例说明:

<!-- HTML --> 
<fieldset> 
  <label for="field" class="arial-font-family larger-font-size text-color mbm">
    Form Label
  </label>
</fieldset>

/*CSS*/ 
<style>
.label-font-family { font-family: arial; } 
.larger-font-size { font-size: 150%; } 
.text-color { color: #313131; } 
.mbm, .mvm, .mam { margin-bottom: 10px !important; }
</style>

// 恶心
<span class="display-block blue-box font-arial padding-20">Party like it’s 1999!</span> 
<span class="display-block blue-box font-arial padding-20">Hey, havelately?</span> 
<span class="display-block blue-box font-arial padding-20">Wassuuuuuuup!</span>

优点:

  • 代码复用率极高,几乎达到100%,不会写多的css
  • 见名知意。class 名,就知道里面的css 是什么了。

缺点:

  • 定义原子结构复杂,想把所有的原子结构定义好,并且可以不复用,是一件很难的事情。但是有一个css库给我们做好了。
  • 由于class 是由于css拼装而成,你会发现css 写的又臭又长。但是真的有被在使用:Twitter Bootstrap按钮生成器

OOCSS

“Object Oriented”直译就是面向对象,对于这个词,大家并不陌生,但是加上一个CSS也就是说Object Oriented CSS,对于这个还是第一次见过,被叫作OOCSS(面向对象的CSS),其实这个东西早在2008年被提出,有些同学也在自己的项目中用过了。但有很多同学并不清楚,就拿我来说,我一开始还以为OOCSS是一个新语言或者是CSS框架,其实都不是,他只不过是一种新的写法。

OOCSS其核心就是用最简单的方式编写最整洁,最干净的CSS代码,从而使代码更具重用性,可维护性和可扩展性。

举例说明: image.png      image.png

<div class="el-message-box">
  //  xx confirm
  //  xx alert
</div>

<style>
  // 好的写法 
  .el-message-bo{
    display: inline-block;
    width: 420px;
    padding-bottom: 10px;
    vertical-align: middle;
    background-color: #fff;
    border-radius: 4px;
    border: 1px solid #ebeef5;
    font-size: 18px;
    box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
    text-align: left;
    overflow: hidden;
    backface-visibility: hidden;
  } 
</stlye>
  
  
<div class="alert">
  //  xx confirm
</div>
<div class="confirm">
  //  xx confirm
</div>

<style>
  // 不好的写法 
  .alert{}
  .confirm{}
</stlye>
  

面向css 的两个原则:

  • 独立的结构和样式
  • 独立的容器和内容

image.png

如何使用面向对象的CSS

  • 创建一个组件库
  • 使用类名为扩展基本对象
  • 坚持以语义类来命名类名

基于类名扩展基本对象

<p class=”metadata postMetaData”>
		<a>Author name</a>commented on<a>21-02-2010</a>@
</p>

语义化的重要性 在制作一个高规模或者说大型的web项目,对于如何给元素命名将是一个挑战性的工作,要在一定的语义环境下确保有语义的类名或者ID名,交且可以重复使用这些有语义的名称,我想大家都非常的头痛,特别是一些新同学。另外随着OOCSS中对基础对象的扩展,让大家更容易跳进了创建“表像类名”的陷井中。 比如大家平时中常定义的类名:leftCol,midCol,bottom,top,bigText,redText,borderText等; 这样的类名是不能重复使用的,在OOCSS中对基础对象提高他的扩展性也带来相当大的障碍。所以始终坚持以逻辑和语义来给元素定义类名才是王道。比如说我们给web页面中的错误信息块(红色背景文本块),我们不应定义类名为“redText”,定义为"warning"将更有语义化,更具有重用性。

优缺点:

OOCSS的缺点

  1. OOCSS适合真正的大型网站开发,因为大型网站用到的可重用性组件特别的多,如果运用在小型项目中可能见不到什么成效。所以用不用OOCSS应该根据你的项目来决定。
  2. 如果没用巧妙的使用,创建组件可能对于你来说是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定还是个维护的噩梦。
  3. 最好给每一个组件备写一份说明文档,有助于调用与维护

OOCSS的优点

  1. 减少CSS代码
  2. 具有清洁的HTML标记,有语义的类名,逻辑性强的层次关系。
  3. 语义标记,有助于SEO。
  4. 更好的页面优化,更快的加载时间(因为有很多组件重用)。
  5. 可扩展的标记和CSS样式,有更多的组件可以放到库中,而不影响其他的组件。
  6. 能轻松构造新的页面布局,或制作新的页面风格。

CSS 架构

需要解决的问题:

  • CSS的可预见
  • CSS的可复用性
  • CSS的可维护性
  • CSS的可扩展性

CSS的可预见

可预见性的css意味着你的规则行为正如你所想,当你添加或更新一条规则,他不应该影响你网站上不想要受影响的部分。对于一个小型网站很少的修改,并不是很重要。但是对于一个有着几十或几百个页面的大型网站,可预见性的css就是一种必要。

CSS的可复用性

Css规范应该是足够抽象的和耦合的,这样你可以根据现有代码部分很快创建出新的组件,而不需要重新编写你已经处理过的样式和问题。

CSS的可维护性

当你的网站需要添加、更新或重新安排一些新的组件和特性,这样做不应该重构现有的css。给页面添加x组件不应该破坏已经存在的组件Y。

CSS的可扩展性

随着你的网站的规模和复杂程度的增长,它往往需要更多的开发人员来维护。可扩展的css意味着可以轻松的由有一个人或一个大型的技术团队管理你的网站。他也意味着你的网站的css架构容易掌握不需要很陡的学习曲线,仅仅因为你是如今唯一接触css的开发人员,但是并不意味着永远是这种情况。

常见的坏习惯

// 过于复杂的选择器
#main-nav ul li ul li div { }
#content article h1:first-child { }
#sidebar > div > h3 + p { }

// 过于通用的名字

.widget {}
.widget .title {}
.widget .contents {}
.widget .action {}

// 定制过多的规则
.widget {
  position: absolute;
  top: 20px;
  left: 20px;
  background-color: red;
  font-size: 1.5em;
  text-transform: uppercase;
}

// 无意义的命名规则
.f23 {    
  background: #fff;    
  border: 1px solid #ff0;    
  font-weight: bold;    
  padding: 10px; 
}

分析原因

上述所有糟糕的实践有一个类似的地方,他们给css添加太多的负担。 这似乎是一个奇怪的问题,毕竟一个样式表,他难道不应该承担大多数(如果不是全部样式)的样式吗?这个不是我们想要的吗? 这个简单问题的回答是yes,但是,像往常一样,事情并不总是那么简单,将内容与表现分离是件好事,但是不能因为仅仅你的css代码跟你的html代码分离,就意味着你的内容与你的表现分离了。换句话说,从你的html中分离出来的所有表现代码,并不能满足这个目标,如果为了工作要求你的css跟html有个密切的联系。 此外,html很少仅仅是内容,他多是用来表示结构的。而且通常这种结构是由没有意义的容器元素组成,不同于容许css隔离某组特定元素。甚至没有表现的类名,这仍然把表现混到html中,但是这是否就是有必要将表现跟内容混合呢? 我相信,介于html和css的目前状况,有必要也是明智的把html和css混合一起作为一个表现层。内容层仍旧可以通过模版和局部模版抽象出来。

参考框架

image.png

样式重置:

重置参考

/*---RESET---*/ 
html, body, div, span, applet, object, iframe, 
h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr,
acronym, address, big, cite, code, del, dfn, em, font, 
img, ins, kbd, q, s, samp, small, strike, strong, sub, 
sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, 
label, legend, table, caption, tbody, 
tfoot, thead, tr, th, td {    
  margin: 0;    
  padding: 0;    
  border: 0;    
  outline: 0;    
  font-weight: inherit;    
  font-style: inherit;    
  font-size: 100%;    
  font-family: inherit;    
  vertical-align: baseline; 
}

参考资料: OOCSS CSS团队精神:CSS最佳实践团队开发