摘自http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html
平時在制作頁面的時候,總會碰到有的元素是100%的寬度。眾所周知,如果元素寬度為100%時,其自身不帶其他盒模型屬性設置還好,要是有別的,那將導致盒子撐破。比如說,有一個邊框,或者說有margin和padding,這些都會讓你的盒子撐破。我們換句話來說,如果你的元素寬度是100%時,只要你在元素中添加了border,padding,margin任何一值,都將會把元素盒子撐破(標準模式下,除IE怪異模式)。這樣一來就會相當?shù)穆闊綍r我們碰到這樣的現(xiàn)象時,也是相當?shù)闹斏鳎袝r甚至無法解決,只能通過改變結(jié)構(gòu)來實現(xiàn)。就算你通過繁瑣的方法實現(xiàn)了,但有于瀏覽器的兼容性而導致最終效果不一致。雖然前面介紹的CSS3屬性中的box-sizing在一定程度上解決這樣的問題,其實今天的calc()函數(shù)功能實現(xiàn)上面的效果來得更簡單(解決自適應)。
什么是calc()?
學習calc()之前,我們有必要先知道calc()是什么?只有知道了他是個什么東東?在實際運用中更好的使用他。
calc()從字面我們可以把他理解為一個函數(shù)function。其實calc是英文單詞calculate(計算)的縮寫,是css3的一個新增的功能,用來指定元素的長度。比如說,你可以使用calc()給元素的border、margin、pading、font-size和width等屬性設置動態(tài)值。為何說是動態(tài)值呢?因為我們使用的表達式來得到的值。不過calc()最大的好處就是用在流體布局上,可以通過calc()計算得到元素的寬度。
calc()能做什么?
calc()能讓你給元素的做計算,你可以給一個div元素,使用百分比、em、px和rem單位值計算出其寬度或者高度,比如說“width:calc(50% + 2em)”,這樣一來你就不用考慮元素DIV的寬度值到底是多少,而把這個煩人的任務交由瀏覽器去計算。
calc()語法
calc()語法非常簡單,就像我們小時候?qū)W加 (+)、減(-)、乘(*)、除(/)一樣,使用數(shù)學表達式來表示:
.elm{width:calc(expression);}
其中"expression"是一個表達式,用來計算長度的表達式。
calc()的運算規(guī)則
calc()使用通用的數(shù)學運算規(guī)則,但是也提供更智能的功能:
使用“+”、“-”、“*” 和 “/”四則運算;
可以使用百分比、px、em、rem等單位;
可以混合使用各種單位進行計算;
表達式中有“+”和“-”時,其前后必須要有空格,如"widht: calc(12%+5em)"這種沒有空格的寫法是錯誤的;
表達式中有“*”和“/”時,其前后可以沒有空格,但建議留有空格。
瀏覽器的兼容性
瀏覽器對calc()的兼容性還算不錯,在IE9+、FF4.0+、Chrome19+、Safari6+都得到較好支持,同樣需要在其前面加上各瀏覽器廠商的識別符,不過可惜的是,移動端的瀏覽器還沒僅有“firefox for android 14.0”支持,其他的全軍覆沒。
大家在實際使用時,同樣需要添加瀏覽器的前綴
.elm {/*Firefox*/-moz-calc(expression);/*chrome safari*/-webkit-calc(expression);/*Standard */calc(); }
通過上面的了解,大家對calc()不在那么陌生,但對于實際的運用可能還是不太了解,那么大家就接下來跟我一起動手,通過實例來了解他吧。首先我們來看一個最常用的實例:
上面的結(jié)構(gòu)很簡單,就是一個div.demo的元素中包含了一個div.box的元素,接下來我們一步一步來看其中的變化。
第一步:添加普通樣式:
.demo{width:300px;background:#60f;}.box{width:100%;background:#f60;height:50px;}
此時的效果很簡單,就是div.box完全遮蓋了div.demo,如下圖所示:

第二步,在div.box上添加border和padding
這一步很棘手的事情來了,在div.box上添加10px的內(nèi)距padding,同時添加5px的border:
.demo{width:300px;background:#60f;}.box{width:100%;background:#f60;height:50px;padding:10px;border:5px solid green;}
為了更好的說明問題,我在div.demo上添加了一個padding:3px 0;
.demo{width:300px;background:#60f;padding:3px0;}.box{width:100%;background:#f60;height:50px;padding:10px;border:5px solid green;}
這個時候大家不知道能否想到問題會發(fā)生在哪?其實很簡單,這個時候div.box的寬度大于了其容器div.demo的總寬度,從而撐破容器伸出來了,如圖所示:

第三步,calc()的運用
為了解決撐破容器的問題,以前我們只能去計算div.box的寬度,用容器寬度減去padding和border的值,但有時候,我們苦于不知道元素的總寬度,比如說是自適應的布局,只知道一個百分值,但其他的值又是px之類的值,這就是難點,死卡住了。隨著CSS3的出現(xiàn),其中利用box-sizing來改變元素的盒模型類型實使實現(xiàn)效果,但今天我們學習的calc()方法更是方便。
知道總寬度是100%,在這個基礎上減去boder的寬度(5px * 2 = 10px),在減去padding的寬度(10px * 2 = 20px),即"100% - (10px + 5px) * 2 = 30px" ,最終得到的值就是div.box的width值:
.demo{width:300px;background:#60f;padding:3px0;}.box{background:#f60;height:50px;padding:10px;border:5px solid green;width:90%;/*寫給不支持calc()的瀏覽器*/width:-moz-calc(100% - (10px +5px)*2);width:-webkit-calc(100% - (10px +5px)*2);width:calc(100% - (10px +5px)*2);}
這樣一來,通過calc()計算后,div.box不在會超出其容器div.demo的寬度,如圖所示:

上面是一個簡單的實例,接下來我們一起來看一個自適應布局的例子:
上面的demo是一個非常簡單而常見的布局效果,在這個布局中,我采用了自適應布局。整個布局包含了“頭部”、“主內(nèi)容”、“邊欄”和“腳部”,并且“主內(nèi)容”居左,“邊欄”靠右,具體結(jié)構(gòu)請看DEMO中的html部分。
接下來,我們主要看看css部分:
1、在body中設置一個內(nèi)距,并附上一些基本的樣式,大家可以根據(jù)自己需要進行不同的設置,此例代碼如下:
body{background:#E8EADD;color:#3C323A;padding:20px;}
2、設置主容器“wrapper”的樣式
主容器的寬度是“100% - 20px * 2”,并且水平居中:
.wrapper{width:1024px;/* Fallback for browsers that don't support the calc() function */width:-moz-calc(100% -40px);width:-webkit-calc(100% -40px);width:calc(100% -40px);margin:auto;}
給不支持calc()的瀏覽器設置了一個固定寬度值“1024px”。
3、給header和footer設置樣式
這個例子中的header和footer很簡單,給他們添加了一個內(nèi)距為20px,其他就是一些基本的樣式設置,那么其對應的寬度應該是"100% - 20px * 2":
#header{background:#f60;padding:20px;width:984px;/*Fallback for browsers that don't support the calc() function*/width:-moz-calc(100% -40px);width:-webkit-calc(100% -40px);width:calc(100% -40px);}#footer{clear:both;background:#000;padding:20px;color:#fff;width:984px;/* Fallback for browsers that don't support the calc() function */width:-moz-calc(100% -40px);width:-webkit-calc(100% -40px);width:calc(100% -40px);}
4、給主內(nèi)容設置樣式
給主內(nèi)容設置了一個8px的邊框,20px的內(nèi)距,并且向左浮動,同時設置了一個向右的外邊距“20”px,關(guān)鍵之處,我們主內(nèi)容占容器寬度的75%,這樣一來,主內(nèi)容的寬度應該是“75% - 8px * 2 - 20px * 2”:
#main{border:8px solid#B8C172;float:left;margin-bottom:20px;margin-right:20px;padding:20px;width:704px;/* Fallback for browsers that don't support the calc() function */width:-moz-calc(75% -20px *2-8px *2);width:-webkit-calc(75% -20px *2-8px *2);width:calc(75% -20px *2-8px *2);}
4、設置右邊欄樣式
給邊欄設置了一個25%的寬度,其除了包含8px的邊框,10px的內(nèi)距外,還有主內(nèi)容外距20px也要去掉,不然整個寬度與容器會相差20px,換句話說就會撐破容器掉下來。因此邊欄的實際寬度應該是"25% - 10px * 2 - 8px * 2 -20px":
#accessory{border:8px solid#B8C172;float:right;padding:10px;width:208px;/* Fallback for browsers that don't support the calc() function */width:-moz-calc(25% -10px *2-8px *2-20px);width:-webkit-calc(25% -10px *2-8px *2-20px);width:calc(25% -10px *2-8px *2-20px);}
這樣一來,大家就看到了上面demo展現(xiàn)的布局效果。經(jīng)過此例的學習,大家是不是會覺得使用calc()用于自適應布局是超爽的呀。此時有很多同學肯定會感吧,苦逼的IE6-8不支持,不敢使用。
最后在給大家提供一個heihgt的實例:
時隔好久沒有寫blog,不知道大家對calc()整明白了沒有,要是沒有的話,繼續(xù)動手寫幾個例子吧。如果您有更好的分享,記得告訴我們喲。