扯一扯前端css的整体架构设计:(2)base基础类的那些事儿
周一下午在实验室写了第一篇博文,有几个人捧场,那咱就得接着下去啊。然后我觉得现在写的内容更多的偏向于谈一下我对于前端css架构的理解和前端经验的一个小总结,所以就把标题里原来的【项目总结】给删掉了。但是这不是说以后文章就不提我手里这个半死不活的类电商网站了,还得接着提,要不然拿什么自黑呢~~
[回顾一下上一篇]
上一篇里我主要针对于我最近写的一个项目的前端结构,开始介绍了一些前端结构的一些知识或者说是经验吧。
为什么前端css也有架构,为什么要考虑css的架构,怎么实现css的简单架构,这些问题在第一篇文章里都有提到,想了解的自行翻上一篇文章吧。
上回说到整个项目快完工的时候,觉得自己的前端css代码确实存在复用不高、命名不规范等毛病,然后四月末看了一本书,醍醐灌顶,发现自己一直采取的架构方式不是很好。我之前的项目包括这个电商网站的前端大部分都是我自己来完成,后端部分他们自己搞,我只要管好我这前端,按时给他们up页面,然后数据绑定一下就ok,有时候顶多帮忙写点分布视图或者是界面里的强类型什么的。因为几乎都是我自己手写的代码,所以在前端上比较随意,采用自己比较习惯的方式来写。在Css布局上,我倾向于把功能划分法和区域划分法混用,说浅显点就是,我的css代码里既有把header、footer的抽象类,也有button、font的抽象类,然后具体到每个界面都有一个定制的css文件等着它。
这种招法有它的好处,就是开发快,不需要考虑太多,直接分析一下界面,把重复出现的模块提取出来,然后规定一种写法就可以。但是这种方法只适用于页面比较少、css文件比较少的小型网站,如果碰到这次的大型网站,比如说购物网站、论坛等等,这一种方法的缺点就暴露出来了:css文件过多、css文件易冲突、模块复用度不高等等。
所以,当看到大牛总结的前端架构方法之后,感觉整个人都不好了。
[开始这篇博客前总结一下]
之前我说到另外的一种前端css架构方式:按照职能方式进行划分。即将所有css文件根据其在项目前端布局中的作用分类,可以分为:
类名 | 在前端布局中的主要作用 | 其他说明 |
base(基础类) |
主要负责重置浏览器默认样式和提供原子级别的样式服务,主要以font、margin、height、width等为主; 作用范围是本网站内的所有界面
|
base.css文件一般不需维护, 但要保证其可靠性 |
common(普通类) |
在base类的基础上,将整个网站的模块进行抽象化,实现代码高度复用;会在网站内经常出现 |
common中模块根据实际使用 可能有差异,可配合原子类进行使用 |
page(页面类) | 利用base中的原子类服务针对特定界面提供css ui,提供页面级别服务,作用范围最小 |
尽量避免团队开发page.css中样式 冲突的问题 |
可以把各层功能范围理解成: 金字塔。
所以,就像上面的表格中说到的,同时我在上一篇博客里面也有提到:
对于一个团队或者一个开发者来讲,它有自己固定的、常用的base.css。因为base层很显然的特点就是高度重用,这一点我们从base在前端布局中的作用上也能看出来, 接下来拆解base的两种功能,咱接着唠。
---------------------------我是一条分割线----------------------------------怎么这么长啊-----------------------------------
[1.重置浏览器默认样式]
为什么要重置?答:因为默认的丑啊。
最简单的重置浏览器默认样式的方法相信很多同志们都用过:
*{margin:0px;padding:0px;}
重置了浏览器为所有页面默认添加的2px的边距和填充值,因为大家都不喜欢把自己的页面像是镶在浏览器里,然后还是个白边儿...
这是一种最简单的浏览器默认样式重置的代码,大部分人也确实都在使用。但是最近看到个Blog里面在谈*选择符,很多f2e认为*选择符的涵盖范围过大,它默认选择的是所有标签,所以它会在浏览器渲染的过程中兼容老式标签,比如说<dir><ins>什么的,所以在浏览器的dom树生成过程中可能会影响效率----------额,对于这个说法,我自己的见解是无所谓,喜欢用*{}的太多了,包括我自己的所有reset类都有这个,然后那个博客中提到的因为*符产生的浏览器效率滞后我觉得几乎就可以不计了吧,挺好的一盘菜不能因为里面一个葱花不好看就不吃了啊(咳咳咳,请叫我烂比喻大湿)
说完最简单的重置浏览器的代码,很多人可能在说:这就够了吧,*{margin:0px;padding:0px}已经把我最不喜欢的浏览器样式取消掉了,别的就不用写了,但是其实浏览器默认样式带来的布局bug或者叫布局丑点还有很多:
img的框、li标签的默认列表样式、table里默认的上下边距和列之间蛋疼的2px的空隙...
还有h标签的默认加粗,没记错的话类似于是font-weight:600:在现在这种扁平化、大图满页面飞的时候,h标签加粗确实很少用了;
所以很多时候为了我们在后续更好的对这些标签进行改造,又为了节省后面的代码量,我们一般将浏览器的重置默认全部写在base.css类里面。上一篇文章里面我好像也提了一下,我个人比较推荐采用yui的reset.css,写的真的很管用,这个reset文件没有对不对或者好不好的说法,只有好不好用的说法,只要适合你自己开发的、能够帮你减少工程量的,就是好用的reset.css。各位看官,完全可以根据自己的需求定制,不要盲目使用。(PS:万一你碰到了个喜欢页面有margin的甲方呢,哈哈哈哈..._(:з」∠)_)
推荐个网站 <a href="http://www.cssreset.com/">http://www.cssreset.com/</a>,一个国外css站,提供了很多种常用的reset文件,提供ctrl+c & ctrl+v 服务,开发利器~~网站截图:↓↓
这里附上比较常用的Yui的reset.css代码吧,里面对h标签的重置真是大快人心~\(≧▽≦)/~收好不谢
1 body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;} 2 table{border-collapse:collapse;border-spacing:0;} 3 fieldset,img{border:0;} 4 address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;} 5 li{list-style:none;}caption,th{text-align:left;} 6 h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;} 7 q:before,q:after{content:‘‘;} 8 abbr,acronym {border:0;font-variant:normal;} 9 sup {vertical-align:text-top;} 10 sub {vertical-align:text-bottom;} 11 input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;} 12 legend{color:#000;}
---------------我也是一条分割线----------------------------------------------------------我好长啊啊啊啊---------------------
[2.原子类功能的设计和实现]
说完了浏览器默认样式重置,接下来扯一扯base层css代码的另一个作用:提供原子级别的样式服务。
说到这里看过上篇的可能明白是什么意思,没看过的,你看完了就明白了= , =
咳咳,因为我们现在讨论的是按照职能划分的css架构,所以base层作为最基础的css架构层,它需要为页面布局尽力做到最多,除了默默的重置一下浏览器默认,它还应该为上两层在布局时提供尽量方便的类,比如说高度类,宽度类,通过这些原子类的组合使用,不依赖于common类和page类也能实现页面最简单的“搭积木”...
很多同学可能疑问:你不是说base层文件不涉及浏览器ui样式、可以适用于任何网站的设计,那你这浏览器的原子类都有点儿啥啊?
有啥?这个要根据你实际的网站使用情况来看,举个我做的电商网站的css文件里面的小栗子:↓↓↓
(请自动忽视上面w960里面写的width:1024px= 。 =,以及每个.w类里面的height:inherit)
一开始没觉得,后来开始写的时候,我真是越发的为自己点赞,就说.w960和.clear30,这两个类在我所有界面里面出现了100+次,要是我当时没有这么写而是给每一个div都需要定个类名,再给它写在page.css里,相信css代码量最少多写200行...而且万一,万一碰到甲方说“你们这个界面切糕区太窄了,再大点儿,我们就喜欢大的!”...然后你没用原子类,然后就熬夜挨个文件改吧....
所以从我上面晒出来的代码里,应该最起码能总结出来:高度和宽度可以抽象出原子类,在实际使用时候:↓(举段例子)
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <style type="text/css"> 6 /*宽度 原子类*/ 7 .w100{width:100px;} 8 .w200{width:200px;} 9 .w300{width:300px;} 10 .w{width:100%;} 11 .win{width:inherit;} 12 /*高度 原子类*/ 13 .h50{height:50px;} 14 .h100{height:100px;} 15 .h200{height:200px;} 16 .h300{height:200px;} 17 .h{height:100%;} 18 .hin{height:inherit;} 19 /*定位 原子类*/ 20 .bc{margin-left:auto;margin-right:auto;}/*就是块状元素居中*/ 21 </style> 22 </head> 23 24 <body> 25 <!--使用距离--> 26 <div class="w h300 bc"> 27 <div class="w300 h100 bc"> 28 </div> 29 </div> 30 31 </body> 32 </html>
从上面这个我随便写了一个类的代码,相信同志们应该彻底明白原子类都是什么,原子类的应该怎么用了。
就是通过简单的原子类的组合就可以直接实现界面初步布局,并且宽度啊、高度这些原子类的数值根据自己使用来定,一般常用的也就是100,200,300~1200左右,有的用不上的就不用加在里面了,千万别.w1,.w2,.w3.....w999,w1000,.w1001,当你想这么干的时候,喝口水冷静一下。
很多人都说你这个原子类可真简单啊,一个样式里面就一条,你上面.w930{width:930px;height:inherit;},你这时候怎么不写height默认继承父元素了呢?
解释一下哈,我上面那么写的原因:1.因为当时脑袋抽了2.后来发现还是有一定道理的,因为我们那个电商网站是个伪全屏,就是上面的导航栏、背景是默认全屏的,但是中间的Mainpart部分其实是有最大宽度限制的,而我的.w930这些宽度原子类,一般是用在mainpart里的,一般一个界面模块就用一个.w960限制一下,直接搞定,而且高度默认继承这个模块的高度~~而且,如果想要覆盖的话,只在标签的class中这么写就可以了:class="w960 h500",就很容易的被覆盖掉了,不影响页面布局的说。
为什么这时候举例子时我每个原子类只写一条呢?因为原子类,原子类啊,提供的就是最小级别的布局服务,你提供那么多,还能叫原子类了么,有违我们的设计初衷啊。要是原子类很赘余冗长的话,那还能叫原子类了么,又变成我们自己定义的一个乱七八糟的类了,而且赘余冗长的话对base.css的通用性来讲,就是啪啪啪打脸啊
咳咳,看完我写的几个原子类后,想必大家可能有一下的想法:
1.你写的就是这么几个类啊,这个我在我的代码里也写呢
答:写出来不等于能用出来呦,只有将原子类的功能集中在base.css里才能发挥其最大作用。我们的目标是:不写一行多余代码!
2.少年啊,你这种原子类的做法,会让一个标签的类名很长啊
答:长就长呗,看不惯你来咬我啊。咳咳,说笑,对于这种类名组合导致类名过长的问题,我想好好解释一下。
下面有这样一个样式,大家来一起实现一下:
最简单的代码:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 </head> 6 <body> 7 <p style="font-size:20px;color:red;margin-top:10px">我喜欢吃卤肉饭</p> 8 <p style="font-size:20px;color:blue;margin-top:20px;margin-left:10px;">天要下雨</p> 9 <p style="font-size:14px;color:red;margin-top:10px;margin-left:10px;">明天不放假</p> 10 </body> 11 </html>
嗯,看上去已经实现功能了,但是作为一个有理想有抱负的前端,怎么能容许css代码与html代码搅在一起呢,必须分开啊!
好吧,看来我们只能这么干了,即把样式抽离成三个类,然后给p赋类吧:↓
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <!--这里为了更方便的展示,就不抽离成css文件了--> 6 <style stype="text/css"> 7 .p1{font-size:20px;color:red;margin-top:10px;} 8 .p2{font-size:20px;color:blue;margin-top:20px;margin-left:10px;} 9 .p3{font-size:14px;color:red;margin-top:10px;margin-left:10px;} 10 </style> 11 </head> 12 <body> 13 <p class="p1">我喜欢吃卤肉饭</p> 14 <p class="p2">天要下雨</p> 15 <p class="p3">明天不放假</p> 16 </body> 17 </html>
但是感觉好长啊,.p1,.p2,.p3的css中确实有很多相同的,而且这里面还没有设置color、border、padding等其他属性,相信设置之后重复部分会更多,所以我们试着简化一下= = 但是好像发现没办法简化,因为任意两个类里面都没有两个一模一样的属性,所以再抽离出一个新类都不太可能了,就算抽离出来,那怎么理解这些类的语意呢?
所以,那怎么破呢?
用原子类啊!看我的↓
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--这里为了更方便的展示,就不抽离成css文件了--> <style stype="text/css"> .f14{font-size:14px;} .f20{font-size:20px;} .cred{color:red;} .cblu{color:blue;} .mt10{margin-top:10px;} .mt20{margin-top:20px;} .ml10{margin-left:10px;} </style> </head> <body> <p class="f20 cred mt10">我喜欢吃卤肉饭</p> <p class="f20 cblu mt20 ml10">天要下雨</p> <p class="f20 cred mt10 ml10">明天不放假</p> </body> </html>
当然这里举的例子比较极端,因为确实每两个标签都没有重复的样式,所以因此导致原子类使用过多。(不要因为这个开始吐槽,下面有解释)
在一个成型网站里,p、h等标签都会有大致统一的样式,比如都不加粗、颜色都是#000,上下边距都是多少,这时候将他们抽离成一个常用组件置于common类里,再配合上原子类,1.类名使用肯定会减少,但是绝对比一个要多2.根据组件进行订制,不影响各界面布局3.快速开发,当编辑器带提示功能的时候简直神速了
前两种方式大家可以看出来,类名很简洁,但是代码比较冗长;最后一种方法(请自动无视我设置的蛋疼样例),类名组合比较长,但是css代码非常简单。
很多图省事的同学可能觉得第一种或者第二种比较好,但是我们要考虑的是,当页面非常多的时候,你不可能为每一次出现的这种样式的标签加一个类,再者现在让你吧一个h3标签也变成这个样式,然后你的类名怎么加,在<h3>里加上<h3 class="p1">?不觉的而很怪吗= =
而类名比较长的时候,但是我开发快啊!哪怕因为类名比较长导致html代码看起来不太轻盈,但是因为使用这种方式给维护、重构带来了切实的方便。而且这种利用原子类进行布局更适合于团队开发,再强调一下啊,我们是靠谱前端,我们不能拿一个单页面网页和一个人的前端团队来说事儿啊。不用原子类,一个P标签的样式可能小A程序员已经写过很多次了,同时跟他一起开发的小B同学不知道啊,他在他的代码里也得自己写好多遍,连个复制粘贴的机会都不给。而利用原子类进行布局的话,每个人只需要提前了解好自己团队本次项目的base和common说明文档,按照规则独立开发,而且进行页面合并时不用担心冲突,毕竟本是同根生嘛。
关于类名使用的问题,以后会开文章接着说,忘了的话记得提醒我,大家一起交流一下开发经验吧。
最后up一下推荐的原子类模式,就简写了,大家用心领会...= =
1 /* 2 下面是我设计的几个简要的原子类,因为篇幅原因就不写全了,大家根据需要自行补上就可以了 3 下面的代码主要是简介一下原子类都可以有哪些 4 */ 5 /*文字*/ 6 .f12{font-size:12px;} 7 .f14{font-size:14px;} 8 .t2{text-indent:2em;} 9 .t4{text-indent:4em;} 10 /*宽度类*/ 11 .w{width:100%;} 12 .win{width:inherit;} 13 .w10{width:10px;} 14 /*高度类,与宽度相似*/ 15 .h10{height:10px;} 16 /*定位类*/ 17 .bc{margin:0px;margin:0px;} 18 .fl{float:left;} 19 .vm{vertical-align:central;} 20 .block{display:block;} 21 .none{display:none;} 22 .clear{clear:both;} 23 /*边距类*/ 24 .m10{margin:10px;} 25 .mt10{margin-top:10px;} 26 .ml10{margin-left:10px;} 27 /*填充类,与边距相似*/ 28 .p10{padding:10px;} 29 /*当然,当你一个网站设计图确定之后,你可添加一些颜色基础类,但是这个可就不适用所有网站了*/ 30 .cred{color:#F00;} 31 /*其他常见的还有border边框类、boxshadow类、lineheight行高类....*/
当然,大家看完blog之后可能觉得这种架构方式很简单,但是要真正使用起来应该是另一种感受了,所以我推荐看完的或者说有感受的可以在下一个自己手头的网站里尝试一下子,反正又不会怀孕~~同样,那些觉得我说的狗屁不是的同志们,也可以考虑尝试一下,然后我们边用边改进。我也只是个学生,还在学习中,大家互相进步吧。
最后说一下,前几天有人看完Blog之后跟我说,写个css你还考虑这么多,累不累啊,直接写不就完了?
我想说的是,请叫我靠谱前端。
就说这么多吧,下一篇我们common层见,预计几天后发,最近有点写累了,学校事情也好多。
么么哒,各位安!