作为一个前端,你敢说自己懂css,敢自信的说自己精通css吗?css编写很简单,但是初期的结构设计,后期的维护是一项非常消耗脑力的事情。
在这里,抛出两个名词:oocss和BEM.
什么是oocss?
还没了解过的可以看这篇文章 OOCSS vs. OOSCSS
相信大家都用过bootstrap,bootstrap就是典型的面向对象css,即oocss.
面向对象的CSS是一种容易重用的一种CSS规则,这里关键的一点就是如何在页面中识别,创建和模块化可重用的对象,并在页面中任何需要的地方重用,并扩展其附加功能。所以我的理解是,oocss是一种可重用,样式分离,耦合度低的css.
缺点:
- OOCSS适合真正的大型网站开发,因为大型网站用到的可重用性组件特别的多,如果运用在小型项目中可能见不到什么成效。所以用不用OOCSS应该根据你的项目来决定。
- 如果没用巧妙的使用,创建组件可能对于你来说是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定还是个维护的噩梦。
- 最好给每一个组件备写一份说明文档,有助于调用与维护
- 创建了数千行CSS,但有可能这些CSS永远不会被使用。比如Twitter Bootstrap
- 样式(CSS)和结构(HTML)藕合太紧
优点:
- 强调重用,减少CSS代码
- 选择器简洁
- 可扩展类
- 强调风格与内容分离
- 强调内容与容器分离
- 具有清洁的HTML标记,有语义的类名,逻辑性强的层次关系
- 语义标记,有助于SEO
- 可扩展的标记和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。
oosass是可伸缩,面向对象的CSS,其实它就是OOCSS的一个变异体,进化体。
oosass的特点:
- 没有CSS,只有Sass
- 通过%placholder来声明视觉对象
- 可以通过mixin创建可重复的CSS
- 语义化的类名在DOM中声明,而视觉化类名在Sass中声明,否则不可能使用CSS构建UI结构和框架
- 通过Sass来扩展类,而不是通过DOM来扩展类
举个例子,上述代码可以变为:
%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 -->
优点
- 解决了命名空间的问题
- 多人协作时,只要有文档清楚标注规则,后来人可以很轻易的读懂,接手
- 更易于维护
缺点
- 容易写的又长又丑
- 代码量比较多,没这么简洁
- 需要完善的说明文档和规则
我的理解
个人觉得,如果从组件来说,使用BEM很不错,定制化样式就用oosass,两者结合使用,纯属个人观点,欢迎提出你的意见及实践。毕竟我只是纸上谈兵。
参考文档
www.w3cplus.com/preprocesso…
www.w3cplus.com/css/oocss-c…
segmentfault.com/a/119000000…
www.w3cplus.com/css/fifty-s…