原文地址。本文从属于Web 前端入门与最佳实践。css
CSS的学习是一个典型的低门槛,高瓶颈的过程,第一次接触CSS的时候以为一切是如此简单,直到后面越学愈加现本身一无所知,建议看看张鑫旭老师的说说CSS学习中的瓶颈。本文则是从四个方面来讨论如何编写可扩展、可维护的CSS代码:html
使用合理的语义化命名前端
模块化git
遵循命名规范github
遵循单一职责原则sass
在HTML与CSS中都存在着语义化标记的概念,Semantics便是单次的语义和其关联,在HTML中一个简单的示意以下:app
<!-- bad --> <div class=”footer”></div> <!-- good --> <footer></footer>
语义化的HTML可以比较直接的表示出某个标记的功能,另外一方面,Semantic CSS会更加地抽象与主观化。编写语义化地CSS代码意味着你选定的样式类名要可以简单明了的反映出结构与功能信息。另外一方面,样式类命名的时候能够不用太过具体化,这样也方便你复用样式类。模块化
这里咱们以Medium的CSS进行一个说明:wordpress
<div class="stream"> <div class="streamItem"> <article class="postArticle"> <div class="postArticle-content"> <!-- content --> </div> </article> </div> </div>
从上述代码中,你能够迅速辨别出结构、角色和含义。父类为stream
,表明着一系列文章的列表。而第一个子类为streamItem
,即列表中的某个文章的实体,这就明显表现出了子类与父类之间的从属关系。另外,这样一个类与结构能够在任何包含文章的页面上完成复用。对于可读性较好地HTML与CSS代码,不该该像一本书,而应该像一个故事,一个故事中会存在角色和角色之间的关系,而这种更多的语义化地CSS能够较好地提示你整个代码的可维护性。下面推荐几个深刻阅读的文章:post
[About HTML semantics and front-end architecture](
http://nicolasgallagher.com/a...
在像React这样的基于组件的项目中,模块化就是根本地准则。经过建立可复用可组合的模块能够将整个系统合理解耦。
上图中每一个蓝色块内就表明一个组件:
<div class="stream"> <div class="streamItem"> <!-- product info --> </div> </div>
大部分的组件又能够拆分为更多的小组件:
每一个Stream Item都含有一个缩略图和特征信息:
<!-- STREAM COMPONENT --> <div class="stream"> <div class="streamItem"> <!-- POST COMPONENT --> <div class="post"> <img src="thumbnail.png" class="postThumbnail"/> <div class="content"> <!-- product info --> </div> </div> </div> </div>
由于stream组件不依赖于其子组件,所以能够随意地修改post类而不会对stream类有明显地影响。通常来讲,代码之间的耦合程度越低,代码的可修改性与可维护性就越好。
深刻阅读:
目前已经有了不少的优秀的CSS命名约定规范,不过最好的CSS命名规范仍是最适合本身的,所以笔者本身的感受就是选一个最顺眼的命名约定而后将它改形成适合本身的项目的规范。
我我的最喜欢的一个命名规范就是BEM:
BEM是最简单,不过也是最严格的命名规范:
.block {} .block__element {} .block--modifier {}
上述代码中的Blocks表明了高等级的一些类,Elements则是Blocks的子元素,而Modifiers表明了不一样的状态。
<div class="search"> <input type="search__btn search__btn--active" /> </div>
在上述例子中,search类是一个Block,而Search Button则是它的一个子元素,若是你但愿修改按钮的状态,那么应该添加一个相似于active的Modifier。另外你须要记住的是,将来你工做的代码库里颇有可能会出现多个命名规范,你也要学会兼容并包,可以接受学习其余的一些标准。若是你但愿对于BEM进行深刻了解,那么能够阅读如下文章:
SRP原则即只每一个模块或者类只应承担软件系统中的某个单一功能,而且该职责应该完整地封装在类的内部,即对外屏蔽内部实现。而具体到CSS的领域里,SRP意味着某个代码片、类或者模块只应该作一件事。而在CSS的文件组织上,意味着像Carousels、Navigation Bar这样的组件应该有本身独立的CSS文件。
/components |- carousel |- |- carousel.css |- |- carousel.partial.html |- |- carousel.js |- nav |- |- nav.css |- |- nav.partial.html |- |- nav.js
另外一个常见的文件组织方式就是按照功能进行文件组织,举例而言,在上述的代码片中,全部关于Carousel的文件都应该被放到同一个文件夹中。经过这种方式能够将文件索引变得更加容易。一样地,对于常见的全局样式而言,也须要适用于独立地全局样式:
/base |- application.css |- typography.css |- colors.css |- grid.css
在上述例子里,不一样类型的全局样式须要分割到不一样的文件中,这样的话若是你须要去更改你的颜色等等样式,那就很容易找到修改哪一个文件。不管哪一种文件组织方式比较顺眼,你都应该遵循统一的SRP原则。若是某个文件变得冗余臃肿,你应该考虑根据逻辑或者其余东西对内容进行切分。关于文件组织结构与CSS结构方面地深刻阅读:
对于每一个独立的CSS类而言,都应该只包含一个功能。换言之,应该根据关注点的差别将样式切分到不一样的类中,这里有个小例子:
.splash { background: #f2f2f2; color: #fffff; margin: 20px; padding: 30px; border-radius: 4px; position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
在上面这个例子里,咱们搞错了某些关注点,splash
类不只包含了其本身的展现的样式与逻辑,还定义了部分关于其子元素的样式,所以须要切分到两个单独类中:
.splash { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
.splash__content { background: #f2f2f2; color: #fffff; padding: 30px; border-radius: 4px; }
深刻阅读: