元素寬度:在瀏覽器中顯示的占位寬度。
在瀏覽器的默認計算方式下,塊狀元素的寬度計算方式為:左右border+左右padding+左右marging+內容寬度width。
反默認瀏覽器計算方式:如果我們不想要瀏覽器按照這種計算方式計算寬度,則要用到CSS3中的bos-sizing屬性。box-size的取值為:content-box/padding-box/border-box.
(1)content-box(w3c標准):這種計算方式要求將瀏覽器width屬性應用到內容上,所以計算方式與瀏覽器一樣 ,沒必要設置
(2)padding-box:這種計算方式中width屬性=內容寬度+padding寬度*2
(3)border-box(傳統IE瀏覽器):將width屬性應用到border區域(包含border大小),width=內容寬度+border寬度+padding寬度,border變化只影響內容寬度
Box-sizing與盒模型(box-model)的關系。(box-model是CSS的一個重要屬性)。
(1)box-sizing是box的一個屬性,遵循盒模型的原理。
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(此處的內容高度為在W3c標准瀏覽器中的內容高度,在IE傳統中的值實際為IE中盒子內容+border+padding) + 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;
}
IE6以下版本瀏覽器的寬度包含了元素的padding,border值,換句話來說在IE6以下版本其內容真正的寬度是(width-padding-boder)。用內外盒來說的話,W3C標准瀏覽器的內盒寬度等於IE6以下版本瀏覽器的外盒寬度。這樣下來我們就需要在IE6下的版本寫Hack(為了解決瀏覽器兼容性二overriden的css代碼,專門正對某一元素或瀏覽器而寫(技術的發展、瀏覽器的升級是的很少人在用低版本的瀏覽器但是不排除有人在用,為了更好地市場都必須要考慮到這點))統一其內外盒的寬度,關於如何處理這樣的兼容問題,我在這里不多說,感興趣的朋友可以點擊這里。那么瀏覽器發展到今天,世面上用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;
}
效果:
http://cdn1.w3cplus.com/cdn/farfuture/2mvEs4zrs4iUso73VPTJejYUDipgO09v-WLSTOSI3ts/mtime:1341237506/sites/default/files/box-sizing-demo1.jpg
上面效果圖讓大家很明顯的區分開了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;
}
效果:
http://cdn2.w3cplus.com/cdn/farfuture/OjbLf0yyNYv2fbzgioth3CCjEM9bU3P1rCdcwlEbG4A/mtime:1341237508/sites/default/files/box-sizing-layout-demo1.jpg
到目前布局來說一點問題都沒有,那是因為我們子元素寬度加起來剛好與元素的是相等,那么我們現在來變動一下,如果根據設計需要,每個塊中內容都離邊緣有 10px的距離,那么我們先來看看基header,left,main-content,footer這幾個塊加一個padding:10px,看看有什 么變化:
.innerPadding {
padding: 10px;
}
效果:
http://cdn.w3cplus.com/cdn/farfuture/ZHBUgZQQWxI43PjkeI7zBsFfn1BsLIIH95xhmY0o7QU/mtime:1341237508/sites/default/files/box-sizing-layout-demo2.jpg
上圖清晰告訴我們,加了一個padding,惡夢就開始來了,header,footer撐破容器伸出去了,main-content也被掉到left的 下面了。跟剛才當初的效果可是完全不一樣的呀,有人可能會問,如果我不使用padding我只使用border什么怎么樣呢?大家猜猜會怎么樣?不用猜 了,馬上換個代碼給大家看看,我們只要把剛才的padding注掉換成border,如下所示:
.border {
border: 10px solid yellow;
}
效果:
http://cdn.w3cplus.com/cdn/farfuture/_xN5bM8kQ8CVkGz8nl5cTDKDOE7U8IkNiriqlpqoEvQ/mtime:1341237509/sites/default/files/box-sizing-layout-demo3.jpg
上圖是去掉了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;
}
效果:
http://cdn1.w3cplus.com/cdn/farfuture/0zfeCPqnRtj4j4Mw-mAiS89Jcy_TYGnUyKiE0IEAXUM/mtime:1341237509/sites/default/files/box-sizing-layout-demo4.jpg
通過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;
}
(可以用通用適配器*進行hack)
同樣我們來看看其各元素在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上的運用,當然他可能還有別的地方運用更好,有待於我們去發掘,如果你們發現有關於這方面更好的知識,記得一起分享喲。