從div盒子模型談如何寫可維護的css代碼,divcss

來源:互聯網
上載者:User

從div盒子模型談如何寫可維護的css代碼,divcss

市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。在眾多的語言設計模式中我唯獨找不到關於CSS設計模式的資料,即使在網上找到類似內容,細細一看之下才發覺是南轅北轍。經過浩瀚文章搜尋發掘下依舊一無所獲之後,直接導致了我萌生一股寫一篇CSS設計模式的衝動,至此寫下這篇文章,其中敘述如有不當之處,也懇請各位提出意見,分享出您寶貴的經驗。

在寫頁面之中,width, margin, padding這三個CSS屬性可以說是用到頻率最高的幾個屬性之一。但根據我的觀點來看,許多人,甚至於大多數前端對於這三個屬性的書寫把握上乏善可陳,以至於相容和靈活性不得兼顧,導致日後的開發維護成本直線上升,代碼不斷增長,覆蓋重寫樣式,接著再修複一個又一個的Bug。這樣的情況下,使用一種合理高效的CSS設計模式不失為一種明智的選擇,個人稱之為:width,margin,padding三權分立模式(以下簡稱三權分立模式)。可以500%提高開發效率的前端UI架構!

什麼是三權分立模式:

說明這個模式之前,必定先要明白什麼是盒子模型,你可以參考如下Firebug的盒模型:

注意:在圖上表示margin的顏色為白色(實質是透明)。Margin比較特別,它不會影響盒子本身的大小,但是它會影響和盒子有關的其他內容,因此margin也是盒模型的一個重要的組成部分。

盒子本身的大小是這樣計算的:

Width:     width + padding-left + padding-right + border-left + border-right
Height:    height + padding-top + padding-bottom + border-top + border-bottom

通過圖中我們得知,Width(物理總寬度)/Height(物理總高度),是由width/height,padding,border三者之和來決定的。但簡單淺顯的盒模型一旦牽涉到CSS中,便會出現不小的意外。

假設,需要要一個300px寬,80px高的盒子,裡面放一段文字,文字離邊有10px間距。那麼一般Html和CSS寫法為:

HTML代碼:

.代碼 
  1. <div class="box">  
  2.   市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。  
  3. </div>  

 

CSS代碼:

.代碼 
  1. .box{width:280px; height:60px; padding:10px;}  

 

來分析一下這段CSS代碼,因為需要滿足300px寬,且文字間隔為10px,所以Width(300px) = width(280px) + padding(10px) X 2。假設過了段時間需要改版,要求為這個Box添加1px顏色為#ccc的邊框,那麼我們再次找到這段CSS,開始動手修改,加個boder:1px solid #ccc;:可以500%提高開發效率的前端UI架構!

CSS代碼:

.代碼 
  1. .box{width:280px; height:60px; padding:10px; border:1px solid #ccc;}  

 

之後測試一下,咦!似乎有點問題,哦,因為加了邊框所以又多了2px像素的寬,所以要減去這2px。

.代碼 
  1. .box{width:278px; height:58px; padding:10px; border:1px solid #ccc;}  

 

測試一下,問題解決了。正當歡心不已準備休息時候,設計師跑來說,根據最新要求,希望能再把文字與邊距拉大,上下邊距為10px,左右改為15px。繼續修改:

.代碼 
  1. .box{width:268px; height:58px; padding:10px 15px; border:1px solid #ccc;}  

 

經過“精確”計算後終於得出了如上的CSS結果。一次又一次的不斷改版,修改的頁面數量越來越大,其中的代碼越發複雜,計算量也越發龐大,你只能一邊為自己的精確到1px像素級的“專業”功力而沾沾自喜,而後又不得不疲於奔波與各個頁面中的寬高計算。就這樣一個又一個只有你才能明白的代碼出現了!

如何才能擺脫這樣的無效代碼問題呢?這裡使用CSS三權分立模式可謂是最佳解決方案。

CSS三權分立模式的核心在於完全分離width,margin,padding這三個CSS屬性,一個class裡只能擁有三個屬性裡的其中一個,而通過增加一個額外標籤使得能夠通過多個class控制元素的外觀,解除三者的耦合。

就如以上問題為例,重寫300px寬,80px高的盒子,文字離邊有10px間距。使用三權分立模式下的寫法為:

Html代碼:

.代碼 
  1. <div class="box">  
  2.   <div class="roundBox">  
  3.     市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。  
  4.   </div>  
  5. </div>  

 

CSS代碼:

.代碼 
  1. .box{width:300px; height:80px;}  
  2. .box .roundBox{padding:10px;}  

 

這裡的寬度、高度、間距的數值同需求完全一致,無需計算。接下來遇到改版問題為Box添加1px顏色為#ccc的邊框,只需這麼修改: 可以500%提高開發效率的前端UI架構!

.代碼 
  1. .box{width:300px; height:80px;}  
  2. .box .roundBox{padding:10px; border:1px solid #ccc;}  

 

直接為內部標籤class上添加邊框,單刀直入添加邊框屬性即可。最後一關如需把文字與邊距拉大,上下邊距為10px,左右邊距為15px。

.代碼 
  1. .box{width:300px; height:80px;}  
  2. .box .roundBox{padding:10px 15px; border:1px solid #ccc;}  

 

注意:上例可以看到padding與border其實在“寬度佔有”的性質上是一致的(從某個角度來說把border設定為透明再設定一定寬度就是變相的padding),所以完全可以讓這倆個屬性寫在同一class裡,二者性質類同,無需再分離這倆個屬性。

我們可以看出使用三權分立模式書寫代碼的簡潔與高效,而且從可讀性及維護性上有質的飛躍。唯一多的就是為內部添加一個額外的標籤保證padding/border不會與width產生幹擾,解除二者的耦合關係,這也是獲得可維護性需要付出代價。

在剛才的例子中似乎忽略了另外一個屬性——Margin。這裡的Margin在三權分立模式中的立場相對於上面的width與padding耦合強度下似乎並沒有那麼明顯,但以我的個人觀點上來看:Margin的分離是三權分立模式之中最為重要的一環。為什麼Margin在這裡如此重要?因為這裡可以看出一名前端開發人員功力素養——代碼可重用性。

提及代碼可重用性,任何一門電腦語言都有所闡述,而CSS代碼可重用性對於一名前端來說不亞於對JS重構的重要性。CSS的可重用性會直接影響HTML代碼的可複用性。

再回頭看如上代碼,這裡的盒子僅僅是一個頁面的一小部分而已。縱觀整個網站,不會也不可能出現只需要一個模組的頁面。每寫一個模組,將來就要和各式各樣的頁面進行整合、維護、開發。

繼續上面例子,現在我們做好了這個模組,開始行進頁面的整合。假設這個模組所放的位置同左邊的間隔需為10px,同上方模組間隔15px,可能會這麼寫: 可以500%提高開發效率的前端UI架構!

.代碼 
  1. .box{width:300px; height:80px; margin:15px 0 0 10px;}  
  2. .box .roundBox{padding:10px 15px; border:1px solid #ccc;}  

 

這裡的寫法原本是沒有大過錯的,既然提出了Margin分離的重要性,當然不會那麼簡單的糊弄過去的。記住:你所寫的每一個模組的代碼將來都會有被複用到另外一個頁面(項目)的可能性,甚至於我曾看到過一個模組被幾個不同的頁面反覆重用。

說到這裡,繼續下去,假設這個模組需要在另外一塊地方使用,而那裡設計位置要求必須是同上方間隔為0px,離左邊5px。內容結構完全一致,遇到這樣的情況,你會如何解決?

一般遇到這種情況,第一種做法有人會對原先代碼視而不見,直接重寫一份新的HTML和CSS。你別說,我還真遇到過。第二種做法或許會這麼修改HTML和CSS:

HTML代碼:

.代碼 
  1. <div class="box anotherPlace">  
  2.   <div class="roundBox">  
  3.     市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。  
  4.   </div>  
  5. </div>  

 

CSS代碼:

.代碼 
  1. .box{width:300px; height:80px; margin:15px 0 0 10px;}  
  2. .box.anotherPlace{margin:0 0 0 5px;}  
  3. .box .roundBox{padding:10px 15px; border:1px solid #ccc;}  

 

添加一個結合選取器限定覆蓋原先的margin屬性,這一類做法是比較聰明的辦法,如果這個模組多次重用則添加多個結合選取器即可,我曾今也常使用類似做法來修複各類的Bug。可以500%提高開發效率的前端UI架構!

或許上面的方法的確可以解決類似的問題,但作為一名喜歡沒事瞎琢磨點東西的我來說總覺得有什麼地方不對。在不斷的思考下最終發現這個並非是真正重用,只是一種“修複”,從某個角度上來說,這不過是為這個模組打一個“補丁”。一個又一個結合選取器不就是一個個小的補丁嵌入到不同的頁面中去麼,依然會有那麼多多餘的代碼會被寫入,這並非是理想中的重用。

理想的重用是不添加任何代碼,僅僅使用原先的代碼就能完全搞定所有的模組,雖然只是理想狀態,但我們可以不斷的向這個目標靠近。在研究一些CSS庫後,發現很多地方同自己的想法不謀而合,其中Margin分離就是其中之一,我們來看看以下程式碼片段:

CSS代碼:

.代碼 
  1. .m10{margin:10px}  
  2. .m15{margin:15px}  
  3. .m30{margin:30px}  
  4. .mt5{margin-top:5px}  
  5. .mt10{margin-top:10px}  
  6. .mt15{margin-top:15px}  
  7. .mt20{margin-top:20px}  
  8. .mt30{margin-top:30px}  
  9. .mt50{margin-top:50px}  
  10. .mt100{margin-top:100px}  
  11. .mb10{margin-bottom:10px}  
  12. .mb15{margin-bottom:15px}  
  13. .mb20{margin-bottom:20px}  
  14. .mb30{margin-bottom:30px}  
  15. .mb50{margin-bottom:50px}  
  16. .mb100{margin-bottom:100px}  
  17. .ml5{margin-left:5px}  
  18. .ml10{margin-left:10px}  
  19. .ml15{margin-left:15px}  
  20. .ml20{margin-left:20px}  
  21. .ml30{margin-left:30px}  
  22. .ml50{margin-left:50px}  
  23. .ml100{margin-left:100px}  
  24. .mr5{margin-right:5px}  
  25. .mr10{margin-right:10px}  
  26. .mr15{margin-right:15px}  
  27. .mr20{margin-right:20px}  
  28. .mr30{margin-right:30px}  
  29. .mr50{margin-right:50px}  
  30. .mr100{margin-right:100px}  

 

以上其實就是一個CSS公用檔案的一段代碼摘抄,其思想引入這些公用的CSS類,單獨定義Margin。通過簡寫命名,即使用頭字母來記憶裡面的屬性,例如:mt15就是margin-top:15px的意思,下面來看我們如何使用它吧。可以500%提高開發效率的前端UI架構!

原先那個模組整合到頁面中需要離上15px,離左10px,使用CSS庫的做法就是這麼寫的:

HTML代碼:

.代碼 
  1. <div class="box mt15 ml10">  
  2.   <div class="roundBox">  
  3.     市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。  
  4.   </div>  
  5. </div>  

 

CSS代碼:

.代碼 
  1. .box{width:300px; height:80px;}  
  2. .box .roundBox{padding:10px 15px; border:1px solid #ccc;}  

 

剔除多餘的結合選取器,選擇可以高度重用的CSS屬性,這裡你或許覺得沒有多大意義,但如果需要把這個模組放入別的頁面呢,就如上面又要放置在同上方間隔為0,離左邊5px的地方,此效用開始發揮作用了,直接修改HTML代碼,無需任何的CSS的修改,模組的高度複用:

HTML代碼:

.代碼 
  1. <div class="box ml5">  
  2.   <div class="roundBox">  
  3.     市面上我們常常會看到各種各樣的設計模式書籍,Java設計模式、C#設計模式、Ruby設計模式等等。  
  4.   </div>  
  5. </div>  

 

這樣子你還會認為原先的選取器做法是正確的麼。個人認為:Margin是阻礙模組重用的最大殺手,因為任何一個組件都或多或少會添加Margin這個屬性來間隔開自身同他人的距離,直接拷貝原先代碼,則先前適用Margin的屬性反而成為了新組件位置的阻礙,及時分離Margin可以有效解除組件同Margin的耦合,達到重複使用的效果。

這就是三權分立模式的全貌,width,margin,padding這三個屬性完全的分離,大大提高的代碼的可複用性,可維護性,解除三者的耦合,為將來的開發維護打下堅實的基礎,也是CSS設計模式的優勢所在。

當然設計模式也有他的二個弊端:

複雜性:獲得可維護性往往要付出代價,那就是代碼可能會變得更加複雜、更難被新手理解。三權分立模式中的匯入公用CSS重用模組,書寫多個class合并代替使用單一class都是所需要考慮和規範的。

效能:多數的設計模式對代碼的效能會有所拖累,這種拖累可能微不足道,也可能完全不能接受,這取決於項目的具體要求。這裡的三權分立模式就需要額外添加一個內部標籤來分離padding屬性。可以500%提高開發效率的前端UI架構!

實現設計模式比較容易,而懂得應該在什麼時候使用什麼模式則較為困難。你應該盡量保證所選用的模式就是最恰當的那種,並且不要過度犧牲效能。這對於個人開發甚至於一個團隊的開發維護都具有莫大的協助,個人認為使用三權分立模式是利遠大於弊的,希望你也能夠瞭解他的思想與作用,在團隊開發中使用他,維護他,三權分立模式現實應用可以協助你和你的團隊開發出更加茁壯的代碼。

寫了那麼多,只希望你能瞭解到使用合理的CSS設計模式可以協助我們最佳化代碼,其最終目的是為了CSS開發維護的高效性和可維護性,而其魅力也在於此。


CSS+DIV寫盒子模型圖

網頁盒子模型存在兩種:
1:標準W3C盒子模型; 2:IE盒子模型(IE瀏覽器預設的模型)。
在兩種不同模型網頁裡,定義了相同CSS屬性的元素顯示效果是不一樣的,下面就用公式來區分這兩種不同的盒子模型。
1:標準W3C盒子模型
寬=width+(padding-left)+(padding-right)+(margin-left)+(margin-right)+(border-left)+(border-right)

高=height+(padding-top)+(padding-bottom)+(margin-top)+(margin-bottom)+(border-top)+(border-bottom)
2: IE盒子模型
寬=width+(border-left)+(border-right)
高=height+(border-top)+(border-bottom)
該模型是IE瀏覽器預設的盒子模型,當然也可以對其變更,在頁面最上方加如下代碼:

1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/...al.dtd">
 
一個div+css盒子模型,普通模板樣本

  代碼可直接運行
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "www.w3.org/TR/html4/loose.dtd">
  <html>
  <head>
  <meta http-equiv="content-Type" content="text/html; charset=utf-8" />
  <title> New Document </title>
  <link rel="stylesheet" type="text/css" href="css/style.css"/>
  <script src="js/dialog.js" language="JavaScript" type="text/javascript"></script>
  <meta name="Generator" content="EditPlus">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <style>
  div,img,a,body,ul,li,span,p{margin:0;padding:0;}
  .clear{clear:both;}
  .ban{
  width:960px;
  height:40px;
  background-color:red;
  border:1px blue solid;
  margin:10px 0;
  padding:10px 10px;
  /*ban的實際高度是height的40+border的2(上下各1px)+padding的20(上下各10px)=62px;寬度同樣 */
  }
  .menu{
  width:960px;
  height:40px;
  background-color:blue;
  border:1px red solid;
  margin:20px 0;
  padding:10px 10px;
  }
  /*ban與menu之間的上下邊距本應是10+20=30,但是因為瀏覽器的margin的上下邊距bug,因而兩者之間的值取其中的較大值,因而為20 */
  .left{
  width:150px;
  ......餘下全文>>
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.