CSS3 Box-sizing

轉載於:http://www.w3cplus.com/content/css3-box-sizing


box-sizingCSS3的box屬性之一。一說到CSS的盒模型(Box model)我想很多人都會比較煩,特別是對於新手,然而這個Box model又是我們CSS運用中比較重要的一個屬性。那麼CSS3Box-sizing跟盒模型有什麼關係呢?第一句話就說了,Box-sizing是CSS3的Box屬性之一,那他當然也遵循CSS的Box model原理,爲了能更好的學習和理解這個Box-sizing屬性,我們有必要先了解一下CSS中Box model的原理。

CSS中Box model是分爲兩種,第一種是W3C的標準模型,另一種是IE的傳統模型,他們相同之處都是對元素計算尺寸的模型,具體說就是對元素的width,height,padding,border以及元素實際尺寸的計算關係;他們不同之處呢?兩者的計算方法不一至:

1、W3C的標準Box Model:

  /*外盒尺寸計算(元素空間尺寸)*/
  Element空間高度 = content height + padding + border + margin
  Element 空間寬度 = content width + padding + border + margin
  /*內盒尺寸計算(元素大小)*/
  Element Height = content height + padding + border (Height爲內容高度)
  Element Width = content width + padding + border (Width爲內容寬度)

 

2、IE)傳統下Box Model(IE6以下,不含IE6版本或“QuirksMode下IE5.5+”):

  /*外盒尺寸計算(元素空間尺寸)*/
  Element空間高度 = content Height + margin (Height包含了元素內容寬度,邊框寬度,內距寬度)
  Element空間寬度 = content Width + margin (Width包含了元素內容寬度、邊框寬度、內距寬度)
  /*內盒尺寸計算(元素大小)*/
  Element Height = content Height(Height包含了元素內容寬度,邊框寬度,內距寬度)
  Element Width = content Width(Width包含了元素內容寬度、邊框寬度、內距寬度)

 

其實原則上來說Box Model是分得很細的,我們這裏主要分了兩個比較明顯的地方,就是外盒模型和內合模型,如上面計算公式所示(後面我將會詳細介紹一下CSS中的Box Model)。這樣說大家可能還不太好理解,下面我們一起來看一個實際的例子,比如說現在有一個叫boxtest的Div,其具有下面一個屬性

 .boxtest {
    border: 20px solid;
    padding: 30px;
    margin: 30px;
    background: #ffc;
    width: 300px;
 }

 

我們先來看一下W3C標準瀏覽器(Firefox,Safari,Chrome,Opera,IE6+)和傳統瀏覽器(IE6以下版本瀏覽器)的Layout截圖

上圖中明顯可以看出IE6以下版本瀏覽器的寬度包含了元素的padding,border值,換句話來說在IE6以下版本其內容真正的寬度是(width-padding-boder)。用內外盒來說的話,W3C標準瀏覽器的內盒寬度等於IE6以下版本瀏覽器的外盒寬度。這樣下來我們就需要在IE6下的版本寫Hack統一其內外盒的寬度,關於如何處理這樣的兼容問題,我在這裏不多說,感興趣的朋友可以點擊這裏。那麼瀏覽器發展到今天,世面上用IE6以下的瀏覽器應該所佔比例相當的少,但不排除沒有人不在用。所以目前瀏覽器大部分元素都是基於W3C標準的Box Model上,但對於form中的有部分元素還是基於傳統的Box Model上,比如說input中的submit,reset,button和select等元素,這樣如果我們給其設置border和padding他也只會往內延伸。關於如何處理form中的這些元素,今日將會藉此機會和大定一起探討一下,那麼現在我們還是先回到今天的正題上。

上面簡單讓大家對CSS的Box Model有了一個初步的概念(如果想了解更多的Box Model相關知識,可以點擊W3C Box Model,另外在這裏有中文版)。下面開始我們今天的主題——CSS3的Box-sizing。

語法:

  box-sizing : content-box || border-box || inherit

 

取值說明

1、content-box:此值爲其默認值,其讓元素維持W3C的標準Box Model,也就是說元素的寬度/高度(width/height)等於元素邊框寬度(border)加上元素內邊距(padding)加上元素內容寬度/高度(content width/height)即:Element Width/Height = border+padding+content width/height。

2、border-box:此值讓元素維持IE傳統的Box Model(IE6以下版本),也就是說元素的寬度/高度等於元素內容的寬度/高度。(從上面Box Model介紹可知,我們這裏的content width/height包含了元素的border,padding,內容的width/height【此處的內容寬度/高度=width/height-border-padding】)。

爲了更能形像看出box-sizing中content-box和border-box兩者的區別,我們先簡單來看一人示例圖,如下所示:

兼容瀏覽器

box-sizing現代瀏覽器都支持,但IE家族只有IE8版本以上才支持,雖然現代瀏覽器支持box-sizing,但有些瀏覽器還是需要加上自己的前綴,Mozilla需要加上-moz-,Webkit內核需要加上-webkit-,Presto內核-o-,IE8-ms-,所以box-sizing兼容瀏覽器時需要加上各自的前綴:

  /*Content box*/
  Element {
     -moz-box-sizing: content-box;  /*Firefox3.5+*/
     -webkit-box-sizing: content-box; /*Safari3.2+*/
     -o-box-sizing: content-box; /*Opera9.6*/
     -ms-box-sizing: content-box; /*IE8*/
     box-sizing: content-box; /*W3C標準(IE9+,Safari5.1+,Chrome10.0+,Opera10.6+都符合box-sizing的w3c標準語法)*/
  }
        
  /*Border box*/
  Element {
     -moz-box-sizing: border-box;  /*Firefox3.5+*/
     -webkit-box-sizing: border-box; /*Safari3.2+*/
     -o-box-sizing: border-box; /*Opera9.6*/
     -ms-box-sizing: border-box; /*IE8*/
     box-sizing: border-box; /*W3C標準(IE9+,Safari5.1+,Chrome10.0+,Opera10.6+都符合box-sizing的w3c標準語法)*/
  }

 

上面主要介紹了box-sizing的理論知識,我們還是理論和實踐結合吧,下面就一起先來看一個簡單點的例子:

HTML Code:

   <div class="imgBox" id="contentBox"><img src="/images/header.jpeg" alt="" /></div>
   <div class="imgBox" id="borderBox"><img src="/images/header.jpeg" alt="" /></div>

 

CSS Code:

  .imgBox img{
     width: 140px;
     height: 140px;
     padding: 20px;
     border: 20px solid orange;
     margin: 10px;
  }
  #contentBox img{
     -moz-box-sizing: content-box;
     -webkit-box-sizing: content-box;
     -o-box-sizing: content-box;
     -ms-box-sizing: content-box;
     box-sizing: content-box; 
  }

  #borderBox img{
     -moz-box-sizing: border-box;
     -webkit-box-sizing: border-box;
     -o-box-sizing: border-box;
     -ms-box-sizing: border-box;
     box-sizing: border-box;
  }
 

 

效果:

上面效果圖讓大家很明顯的區分開了content-box和border-box的區別了,爲了更好的理解,我截了一份他們在Firebug下的一layout分析圖:

Layout分析圖再次證明了box-sizing:content-box是維持了W3C的標準Box Model,而box-sizing:border-box是維持了IE傳統(IE怪異模式)下的Box Model。其兩者區別我在這就不多說了,因爲前面說的很清楚了,如果還有不清楚的同學,只要仔細看一下上面那張Layout分析圖,我想你會恍惚大悟的。那麼box-sizing主要運用在哪些方面呢?我總結了一下,第一點就是我們佈局上,第二點就是表單元素上。爲什麼呢?我想大家在平時佈局中都有碰到當兩個塊元素的寬度剛好是其父元素總寬度時我們佈局不會有任何問題,但當你在其中一個塊加上padding或border時(哪怕是1px)整個佈局就會完全打亂,因爲其總寬度超過了父元素的寬度。第二點表單元素,前面我提到過,form有很多元素還是使用的IE傳統Box Model,針對這兩點,box-sizing將在其身上發揮強大的作用,下面我們分別來看看box-sizing在這兩方面的運用:

一、box-sizing拯救我們的佈局

爲了能更好的說明問題,我們先來模仿一個兩欄佈局,先來看其HTML Code:

  <div class="layoutDemo">
    <div id="header" class="innerPadding border">Header Content</div>
    <div id="content" class="clearfix">
        <div id="left" class="aside innerPadding border">Left Sidebar</div>;
        <div id="main-content" class="article innerPadding border">Main Content</div>
    </div>
    <div id="footer" class="innerPadding border"> Footer Content</div>
  </div>

 

簡單的分析一下,這裏把LayoutDemo的div當作我們頁中的body,而div#header是頁面頭部,div#left是頁面左邊欄,div#main-content是頁面主內容,div#footer是頁面的頁腳,下面我們來模仿一個960的佈局(比例縮小一半),我們加上平時佈局的樣式上去:

 .layoutDemo {
    width: 960px;
    background: #000;     
  }
        
  #header {
    width: 100%;
    background: orange;
  }
        
  #left {
    width: 220px;
    float: left;
    margin-right: 20px
    background: green;
  }
        
  #main-content {
    width: 720px;
    float: left;
    background: gray;
  }
        
  #footer {
    width: 100%;
    background: red;
  }

 

效果:

到目前佈局來說一點問題都沒有,那是因爲我們子元素寬度加起來剛好與元素的是相等,那麼我們現在來變動一下,如果根據設計需要,每個塊中內容都離邊緣有10px的距離,那麼我們先來看看基header,left,main-content,footer這幾個塊加一個padding:10px,看看有什麼變化:

 .innerPadding {
    padding: 10px;
  }

 

效果:

上圖清晰告訴我們,加了一個padding,惡夢就開始來了,header,footer撐破容器伸出去了,main-content也被掉到left的下面了。跟剛纔當初的效果可是完全不一樣的呀,有人可能會問,如果我不使用padding我只使用border什麼怎麼樣呢?大家猜猜會怎麼樣?不用猜了,馬上換個代碼給大家看看,我們只要把剛纔的padding注掉換成border,如下所示:

  .border {
     border: 10px solid yellow;
  }

 

效果:

上圖是去掉了padding只加了10px的邊框,同樣把佈局給打亂了。接着把padding和border同時加進去,反正都撐破了佈局,就破罐子破摔。加上的效果如下:

不上我說,大家都知道上圖是因爲加上了padding和border把佈局給打亂了,下面主要看如何用box-sizing來修復這個撐破的佈局,前面介紹了,上圖中box-sizing是取了其默認值content-box,其Box Model完全符合W3C的標準,爲了修復這樣的佈局,我們需要把Box Model改用IE傳統下的解析,這樣一加,我們給他加上下面box-sizing屬性:

  .box-sizing {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -o-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
  }

 

效果:


通過box-sizing:border-box改變了Box Model後,佈局神奇般的好了,記得以前爲了處理這樣的問題,我們需要改變box的寬度或者在box裏面在嵌套一個div,在裏面的div中增加padding和border來達到這樣的效果。從今天開始,我們不需要那樣做了,我們只要通過box-sizing:border-box來改變Box Model回到IE的傳統模式下,就可以實現了,只是有一點遺憾的是,我們IE6和IE7不支持,如果爲了達到一致的效果,在加上你知道CSS Hack如何寫,這樣也並不難,你只要讓IE6和IE7的寬度改變一下,也能達到效果:

  #left {
    *width:180px; 
  }
  #right {
    *width: 680px;
  }

 

通過上面的hack,我們在IE6和IE7下也能正常顯示我們的佈局需求。但是大家說討厭CSS Hack,不想寫,那麼大家在項目中運用時不得不要考慮一下,但對於我們學習CSS3的box-sizing來說是沒有大礙的。

二、Box-sizing統一form元素風格

前面簡單提到form有些input還是支持IE傳統下的Box Model標準,比如說【type="submit"】、【type="reset"】、button、select等,然在搜索box-sizing屬性使用時偶爾發現Roger Johansson早在2004年就發表了一篇關於表單元素樣式測試的文章《Styling form controls》。他告訴我們如果用樣式來控制表單元素在各瀏覽器下的顯示效果是很難,如果還要兼容各系統下的效果更是難上加難。除非使用UI去製作。那麼今天我們就要來看看用box-sizing如何來讓他們達到一致效果:今天我們只要來測試一下submit,reset,button,section,input[type="text"]幾個元素,下面我們先來看其默認狀態下的效果(模式是在<!DOCTYPE HTML>):

Html Code:

  <form action="#" method="post">
    <div class="form-field">
	<input type="submit" value="submit" class="submit" />
    </div>
    <div class="form-field">
        <input type="reset" value="reset" class="reset" />
    </div>
    <div class="form-field">
	<button class="button">button</button>
    </div>
    <div class="form-field">
	<input type="text" value="text" class="text" />
    </div>
    <div class="form-field">
	<select name="select" id="select" class="select">
           <option value="1">1980</option>
	</select>
    </div>
    <div class="form-field"><input type="checkbox" class="checkbox" />checkbox</div>
    <div class="form-field"><input type="radio" class="radio" />radio</div>
    <div class="form-field"><textarea name="textarea" id="" cols="30" rows="3" class="textarea"></textarea></div>
  </form>

 

CSS Code

   <style type="text/css">
     body {
	font-size: 12px;
     }
     form {
	width: 200px;
	margin: 20px auto;
	padding: 10px;
	border: 1px solid #ccc;
     }
		
     .form-field {
	margin-bottom: 5px;
	background: #cdcdcd;
	padding: 2px;
     }
		
    .submit,
    .reset,
    .button,
    .text,
    .select,
    .textarea {
	width: 80px;
	border-color: red;
    }
			
    .textarea {
	resize: none;
    }
  </style>

 

我們來看其效果,我在效果截圖中附上各個部分在firebug下的layout圖:

DOM元素的Layout圖明顯告訴我們:

1、【type="submit"】、【type="reset"】、button、【type="text"】、select、textarea默認情況下都帶有2px的border;

2、【type="submit"】、【type="reset"】、button默認情況下會有6px的左右padding;height在mac系統下會比在winxp win7系統下少1px,只有16px,(12px的字體時高度爲17px);

3、【type="text"】默認情況下會有1px的上下padding;WinXP和Win7下高度爲15px,Mac系統下爲14px

4、【type="checkbox"】默認情況下會有margin:3px 3px 3px 4px,並且寬/高度默認爲13px(IE6,IE7默認大約是15px,Mac系統下只有9px)

5、【type="radio"】默認情況下會有margin: 3px 3px 0 5px的外邊,並且寬/高度默認爲13px(IE6,IE7默認大約是15px,Mac系統下只有9px)

6、textarea默認情況帶有1px的上下margin;

最後要說的一點是,上面那些常用的form元素只有【type="text"】和textarea兩者是遵循W3C的標準Box Model,而其他幾個都是還是遵循IE傳統下的Box Model。下面我們在把CSS修改一下,我們把margin、padding和border都統一一下。

  .submit,
  .reset,
  .button,
  .text,
  .select,
  .textarea,
  .checkbox,
  .radio {
     margin: 0;
     padding: 0;
     border-width: 1px;
   }

 

同樣我們來看看其各元素在firebug下的Layout分析圖:

Layout圖告訴我們,其margin,border,padding現在都統一了,寬度只有【type="checkbox"】和【type="radio"】在不同的系統和瀏覽器會解析不一樣,最明顯的上面也說過了,這兩個表單元素在IE6和IE7下的寬、高度都是15px,而在Mac系統下是9px,但在WinXP/Win7的Firefox下又是13px,這樣給我們在線上的顯示效果完全帶來了不一樣的風格,這也是大家頭痛的一個地方;另外還有一點需要說明的一點是,別然在上面的Layout中分析【type="submit"】、【type="reset"】、button的寬度一樣,但是在IE6-7之中會隨着內容顯示不同而寬度不同,關於這個問題大家可以參考前面我寫的另一篇文章《input 按鈕在IE下兼容問題》。然而最讓我們頭痛的是表單元素的高度問題,前面也提到過了,在Mac系統下各種表單元素的高度都會比Win系列下少1px,這樣給我們也帶來很大的煩惱。我在網站搜索,看到nwind寫了一篇《如何更好地控制input輸入框的高度》,作者拿了【type="text"】做了很仔細的分析,另外Roger Johansson的《Controlling width with CSS3 box-sizing》一文也做過詳細的分析。從這兩篇文章得知解決這樣的兼容問題我們可以使用CSS3的box-sizing的border-box屬性。下面我截取【type="text"】的解決高度不一到致的方法,運用到表單元素上來

   .submit,
   .reset,
   .button,
   .text,
   .select,
   .textarea,
   .checkbox,
   .radio {
	margin: 0;
	padding: 0;
	border-width: 1px;
	height: 17px;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	-o-box-sizing: border-box;
	-ms-box-sizing: border-box;
	box-sizing: border-box;
   }
				
   .checkbox,
   .radio {
	width: 13px;
	height: 13px;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	-o-box-sizing: border-box;
	-ms-box-sizing: border-box;
	box-sizing: border-box;
   }

 

我們來看看加上了box-sizing:border-box的layout分析圖:

從Layout圖明顯的可以看出,現在元素的參數都統一了,但是IE6和IE7是不支持box-sizing的屬性,所以爲了兼容我們還需要爲他們寫一個hack:

 
  .submit,
  .reset,
  .button,
  .text,
  .select,
  .textarea,
  .checkbox,
  .radio {
     margin: 0;
     padding: 0;
     border-width: 1px;
     height: 17px;
     -moz-box-sizing: border-box;
     -webkit-box-sizing: border-box;
     -o-box-sizing: border-box;
     -ms-box-sizing: border-box;
     box-sizing: border-box;
     /*這裏需要減去border的值,如果padding的值不是0還需要減去padding的值,*/
     *height:15px; 
     *width: 15px;
   }

 

上面詳細介紹了form元素如何使用box-sizing來解決瀏覽器兼容問題。需要提醒大家一點的是,如果你在樣式中沒有對border進行設置的話,那麼表單中除了checkbox和radio外默認都是2px的border,這樣一來你的寬度和高度在都要相應的減去4px。

說到這裏,有關於box-sizing相關方面的知識就介紹完了,本文只介紹了他在佈局和form上的運用,當然他可能還有別的地方運用更好,有待於我們去發掘,如果你們發現有關於這方面更好的知識,記得一起分享喲。

發佈了62 篇原創文章 · 獲贊 2 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章