周一下午在實驗室寫了第一篇博文,有幾個人捧場,那咱就得接着下去啊。然后我覺得現在寫的內容更多的偏向於談一下我對於前端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層見,預計幾天后發,最近有點寫累了,學校事情也好多。
么么噠,各位安!