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

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

一、W3C的標準Box Model:node

  /盒尺寸計算(元素空間尺寸)
  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爲內容寬度)

 

二、IE)傳統下Box Model(IE6如下,不含IE6版本或「QuirksMode下IE5.5+」):css3

  /盒尺寸計算(元素空間尺寸)
  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,其具備下面一個屬性web

.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中的這些元素,今日將會藉此機會和大定一塊兒探討一下,那麼如今咱們仍是先回到今天的正題上。ide

上面簡單讓你們對CSS的Box Model有了一個初步的概念(若是想了解更多的Box Model相關知識,能夠點擊W3C Box Model,另外在這裏有中文版)。下面開始咱們今天的主題——CSS3的Box-sizing。佈局

語法:post

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

 

取值說明學習

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

二、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在這兩方面的運用:

1、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來講是沒有大礙的。

2、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圖明顯告訴咱們:

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

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

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

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

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

六、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上的運用,固然他可能還有別的地方運用更好,有待於咱們去發掘,若是大家發現有關於這方面更好的知識,記得一塊兒分享

如需轉載煩請註明出處:W3CPLUS

相關文章
相關標籤/搜索