浅谈css模块化
模块化是我们经常听到的一个话题,那什么是模块化呢?从字面意义上我们大概能对它有个初步的判断,那么我今天就根据我自己的想法谈谈css模块化。
背景:起初的css长什么样?
/* index.css */ body { margin: 0; padding: 0; font-size: 18px; } .box { background: #333; color: #fff; } .box .list { margin-left: 10px; } .box .list .item { border-bottom: 1px solid #ccc; } .box .list .item:last-child { border-bottom: 0; } .box .list .item a { text-decoration: none; color: #fff; } .box .list .item span { color: red; } .box .list .item a ... { ... }
显然,这里存在几个问题:
1.选择器越来越长,书写累赘(选择器冗长)
2.dom的空间顺序繁杂,不容易分清元素关系(层级结构不清晰)
3.我们很难做到复用,假设另一个页面也需要用到这个box,那么我们必须将box有关的部分粘贴一份,然后去另一个页面复制。(代码难以复用)
这里的问题1,2我们先放一放,看看问题3代码复用怎么解决:
要实现代码复用很简单,我们只需要提供一个公共css库,来存放我们的公共样式以及公共模块即可:
/* common.css */ body { background: #fff; color: #333; font-size: 16px; } .box ... { background: #333; color: #fff; ... } .another-box ... { ... }
然后只要我们在html页面中引入这个css文件和index就可以了,很完美对么。可是如果你在实际中这样操作过就会发现几个问题:
1.如果项目非常大,那么我们只要是有复用需求的css代码,我们都会往common中放,这样会导致common体积过大。
2.假设有一个页面内容非常少,比如404页面,可能只需要用到少量公共样式,但是为了维护问题,我们还是要引入common,这就显得不够“轻”。
3.由于common越写越大,每个页面的私有css样式的可用的名称就越来越少。
总结上面的问题其实只有两个:冗余,污染。冗余的问题在所难免,重就重些,但也不是燃眉之急。污染的问题确实迫在眉睫,如何用一套规范来组织我们的代码?
首先我们把页面分成三个部分:框架,模块,元件。
框架:
框架是指构成页面的基础结构,它是一个页面的筋骨。我们假设有个页面index.html,它的整体最外围表现为一个class为.g-index的div,然后它由页头(.g-hd)、主体(.g-bd)、页脚(.g-ft)三个部分组成:
<!-- index.html --> <!DOCTYPE html> <html> <head> <title>index</title> </head> <body> <div class="g-index"> <div class="g-hd"></div> <div class="g-bd"></div> <div class="g-ft"></div> </div> </body> </html>
模块:
模块是页面上数量最多,同时也是最重要的部分,它是代码复用的主体部分,是一个个按照功能划分的区域,如导航栏、轮播图、登录窗口、信息列表等等,模块之间相互独立,分布在页面上,嵌在框架的各个位置上,组成一个丰富多彩的页面。
还是以index.html为例,我们假设页头有个导航栏模块(.m-nav),主体有个新闻列表模块(.m-news),页脚有个版权声明模块(.m-copy_right)
<!-- index.html --> <!DOCTYPE html> <html> <head> <title>index</title> </head> <body> <div class="g-index"> <div class="g-hd"> <div class="m-nav"> nav </div> </div> <div class="g-bd"> <div class="m-news"> news </div> </div> <div class="g-ft"> <div class="m-copy_right"> copy_right </div> </div> </div> </body> </html>
元件:
元件是独立的、可重复使用的,并且在某些情况下可以作为模块的组成部分的一种细颗粒。比如一个按钮,一个logo等等。某种意义上说,它其实可以等同于模块,因为它们两者的区别只是规模不同而已。模块更强调一个功能完整的整体,而元件则更强调独立性。
我们假设这个页面还需要在页头放个logo(.u-logo),在导航栏中放置一个登录按钮(.u-login_btn):
<!-- index.html --> <!DOCTYPE html> <html> <head> <title>index</title> </head> <body> <div class="g-index"> <div class="g-hd"> <img class="u-logo" alt="logo"> <div class="m-nav"> nav <a href="/logoin" class="u-login_btn">登录</a> </div> </div> <div class="g-bd"> <div class="m-news"> news </div> </div> <div class="g-ft"> <div class="m-copy_right"> copy_right </div> </div> </div> </body> </html>
这样子分类的用处是什么呢?第一,让结构更加清晰。第二,我们常说的语义化。第三,一定程度上减轻了命名空间的“负担”。
但是公有模块和私有模块还是有一定程度上的冲突,于是乎我们可以把共有模块的开头都改为cm-news,私有模块用m-news,这样就不会冲突了。但是我们在页面制作中会遇到过这样一个问题:一个模块一开始是私有模块,但是后面的一个页面也用到了这个模块,于是这个模块应该要变成共有模块(还是维护问题)。但是有一个问题,有时候我们在做一个页面的模块时,根本想不起来之前还有页面中有用到一个相同的模块。怎么办?
索性我们可以顶一个这样的规定:如果不是确定是私有模块,一律设置为公有模块。但是这有一定程度上的引起了common样式的重。
回到一开始的两个未解决的问题
1.选择器冗长
2.结构层级不清晰
:如何解决?
: 你听说过LESS/SASS么?