(本文做者Mrcxt,原文连接:http://blog.csdn.net/mrcxt/article/details/52038884)php
相信写css的人都会遇到下面的问题:css
因而就有了下面的作法:html
因而可知,class的命名真不是一件简单的事,尤为还要兼顾可辨别性与可读性。前端
第一,class跟id不同,class原本就是设计用来能够重复利用的,而id才是设计惟一的(若是遵循BEM,class几乎也都是惟一的了)。 第二,样式是能够覆盖的,并且先按照权重,再按照定义的前后顺序。也许你花了十分钟设计定义的一个class样式,人家分分钟就给你干掉了,这得多恼火;也许这个页面好好的,跑到另外一个页面就跟原先的样式有了冲突。 因此class命名的难就难在既要重复利用,又要避免样式的冲突。若是要重复利用,那么固然是越简单越好,越抽象可用的地方越大,太具体了就完蛋了。而若是要避免样式冲突。BEM(BEM的相关文章能够参考:http://www.w3cplus.com/css/bem-definitions.html)的方式最简单,class都惟一了,那还冲突个毛线;其次就是经过父元素限定做用域,能够搞几个层级,而不是单独一个class定义样式;还有就是追加class,来实现差别化;最后不一样的页面不一样的文件,你用你的我用个人。后端
// BEM .imgslide__item__img{} // 父元素限定 .imgslide .item .img{} // 追加class .img{} .img--special{} // 不一样页面不一样文件 // a.html & a.css .img{} // b.html & b.css .img{}
总之,无论有多难,咱们仍是得试试去解决问题,去寻找一些规律。框架
关于class的命名,其实跟人名也差很少,若是要想别人看得懂,那关键仍是在于可识别性。到目前为止class的命名大概经历了下面几个重要阶段:前后端分离
这个没什么好说的,刚开始学html的都是这样,名字先简单的来,不够再添加1,2,3什么后缀,或者中英混搭等等,以下:ide
h1.title h2.title2 h2.title2-1 h2.title2-2 div.hd div.hd-s div.hd2 div.hd-xiangxi
一个字,太乱。彻底无章程,规律可循,想怎么写就怎么写,写到哪里是哪里。看class去猜意思极可能就是错误的,如.red{color:red;font-size:14px;}
,明明说好的红色,却顺带定义了个字体大小。布局
这个关键在于拼凑组合,足够多的原子类拼成一个完整的样式:post
.fl{float:left;}.fr{float:right;}.pr{position:relative;}.pa{position:absolute;}.tal{text-align:left;}.tac{text-align:center;}.tar{text-align:right;}.fs12{font-size:12px;}
div.fs12.fl.pr.tac div.pa.tal
这种有两个缺点,第一是稍微复杂点的样式都要使用不少class组合,第二是若是要修改样式的时候得修改html文件,而不是css样式,而纯静态的页面是不多的,因此若是是先后端分离的,由php或后端语言渲染页面的话,改个样式还要通知后端同事去修改文件,那估计人家得疯掉。
到了这个时候,css通过这么多年的发展,页面的复杂性已经翻了好几倍了,那些无规划的混沌根本不够用,满眼的class看起来长得都差很少,后面全是1,2,3都不知道标到多少了,殊不知道究竟是啥区别;而原子类已经不适合频繁的修改调整更新,每更新下都是先后齐心合力。因而按职能划分的class命名规则就出现了
// l表示layout, g表示global, m表示mod, .l-960 .l-left .l-right .g-red .g-title .g-price .m-login .m-breadcrumb .m-slide
这种命名方式在必定程度解决了混乱不堪的问题,全部的按照职能划分看起来很美好,不过动不动加个前缀确实不怎么优雅,再者随着mod的增长,这个以m开头的前缀根本就不够用,因而又乱了,有加二级前缀的,也有另起前缀的。
这个估计地球上作前端的都知道吧,实在是太火了,因此不用来解释了。优势就是你只管写你本身的,99.99%的概率不会去干掉别人的样式,class实在太长了,能同样那得多高的概率啊。缺点仍是class太长,太长,太长,重要的事情说三遍。通常都记不住本身定义的class,写css的时候只好对着去拷贝。而后最痛苦的就是去修改更新,明明很简单的东西,而后你还要搞个超长的class,那叫一个烦躁,想一想都懒得动手。
其实每一个命名的发展经历都有其特定的历史意义,也固然有其价值。因此吸收之长,弃之短缺就很好了。比喻写简单demo的时候,咱们就能够用到混沌阶段的命名,足够简单,不须要纠结思考;而原子类尤为是一些简单的样式,如一行代码就能够搞定,起个class名甚是纠结,还不如直接上原子类;至于模块类,说真的应用的场景就更多了,如布局,js操做类等;而BEM咱们一样可借鉴其思想,如.class.class--name
使用--
表示特殊化,以区分-
。 这里咱们站在前人的肩膀上,试着去开辟一条道路,能够兼顾简洁可读性及可理解辨别性。固然class的简洁确定离不开关键词的应用,这里咱们先来过一遍常见的class关键词。
有了关键词以后,咱们先来制定一些简单的规则
.item-img
.item-img.item-img--small
表示在.item-img
的基础上特殊化.active, .checked
icon-
为前缀(字体图标采用.icon-font.i-name
方式命名)。.slide, .modal, .tips, .tabs
,特殊化采用上面两个中划线表示,如.imgslide--full, .modal--pay, .tips--up, .tabs--simple
js-
前缀.a.b.c.d
关键词及规则都有了,如今能够进入本文的核心的核心,实战操做。
以布局入手,大概结构以下:
header.header>.inner-center section.section-feature>.inner-center // if section.section-main>.inner-center section.section-postscript>.inner-center // if footer.footer>.inner-center
具体可参考HTML整站结构设计,这里咱们能够看出都是些简单的关键词,比较好理解,一看就知道是什么。 如今问题来了,若是其余地方也要用到这些关键词怎么办? 修饰关键词 以header为例,咱们能够添加前缀表示不一样的header,如区块头部.block-hd
(hd为header简写),modal头部.modal-hd
,文章头部.article-hd
。 一样标题也能够分为,页面标题.page-tt
(title的简写),区块标题.block-tt
等。 一样,这给咱们提出了第二个问题,若是要特殊化某个class该怎么办? 特殊化class 以上面的tt为例,大概有三种办法: 第一种犯法:直接修改class,将.page-tt
修改为.page-user-tt
(能够采用scss的%
先定义共用的代码)。 第二种办法: 追加class特殊化,根据咱们上面定义的规则,在.page-tt
上追加一个class成为.page-tt.page-tt--user
,注意.page-tt--user
不是一个独立的class,它使基于.page-tt
这个基础上的。 第三种办法: 使用父类,给一个范围,因而造成.page-user .page-tt
。 通常咱们使用的是第二种和第三种办法,由于这两种都有共同的.page-tt
,能够比较方便控制一些基础共有的样式。 由第三个经过父类控制的办法,咱们进入第三个要讨论的问题,层级结构 层级 最适合层级的例子莫过于ul>li
结构了,以下面的结构:
<ul> <li> <a href="#"><img src="" alt=""></a> <h3><a href="#"></a></h3> <p></p> </li></ul>
通常来讲咱们也有两种办法定义层级,第一种为继承式,第二种为关键词式。
// 继承式 ul.card-list li.list-item a.item-img-link>img.item-img h3.item-tt>a.item-tt-link p.item-text // 关键词式 ul.card-list li.item a.field-img-link>img.field-img h3.field-tt>a.field-tt-link p.field-text
由上能够看出继承式通常子元素接着父元素的最后一个单词如li接着ul的list
,而li的子元素接着li的item
;至于关键词式则彻底由关键词来表示层级,list>item>filed
正好构成三层等级。 最后由咱们的层级进入咱们最后一个问题,如何控制样式的范围 样式范围 这里以腾讯课堂的课程详细页右边栏为例,以下图: 三个区块的基础框架为:
.aside-block.block--xxx> h3.block-tt .block-bd
其中.aside-block.block--xxx
用到了咱们的特殊化class,而.block-tt
,block-bd
则使用了咱们的修饰关键词,至于.aside-block
与它的子元素之间则使用了咱们上面说的继承式层级。如今根据这个层级结构咱们定义基础样式以下:
.aside-block{ .block-tt{} .block-bd{} }
假设这里的联系机构区块的标题不同,咱们则能够:
.block--contact{ .block-tt{} }
固然若是自己有5个区块,2个标题同样,另外三个标题又同样,也许咱们就有须要给.block-tt
追加一个特殊化class,或者给aside-block
特殊化一个class,如:
.aside-block{ .block-tt{ &.block-tt--special{} } .block-bd{} } // 或 .aside-block{ &..aside-block--special{ .block-tt{} } }
基础框架讨论完毕以后,就轮到咱们的内容了,以联系机构为例: 使用ul>li
结构,因此样式是另一个独立的范围,不嵌套在以前的.aside-block
里面,html及css代码以下:
ul.contact-list li i.item-icon.icon-font.i-xxx a.item-tt p.gray
这里咱们li没有设置class,而p使用了一个全局的class.gray
.gray{} .contact-list{ li{} .item-icon{} .item-tt }
同理若是咱们有其余地方应用这个能够拷贝过去,而若是须要一点调整,咱们可使用父元素来控制,如这里咱们可使用.block--contact
来进一步调整contact的样式,如:
.block--contact{ .contact-list{ li{} } }
至此,咱们的class命名方法讨论完毕,说到底就是先记住一些必备的基础关键词,而后合理应用上刚才提出的修饰关键词,特殊化class,层级及最后的样式范围就能够了。