平時(shí)在制作頁面的時(shí)候春贸,總會(huì)碰到有的元素是100%的寬度。眾所周知遗遵,如果元 素寬度為100%時(shí)萍恕,其自身不帶其他盒模型屬性設(shè)置還好,要是有別的车要,那將導(dǎo)致盒子撐破雄坪。比如說,有一個(gè)邊框,或者說有margin和padding维哈,這 些都會(huì)讓你的盒子撐破绳姨。我們換句話來說,如果你的元素寬度是100%時(shí)阔挠,只要你在元素中添加了border,padding,margin任何一值飘庄,都將 會(huì)把元素盒子撐破(標(biāo)準(zhǔn)模式下,除IE怪異模式)购撼。這樣一來就會(huì)相當(dāng)?shù)穆闊┕蛳鳎綍r(shí)我們碰到這樣的現(xiàn)象時(shí),也是相當(dāng)?shù)闹?jǐn)慎迂求,有時(shí)甚至無法解決碾盐,只能通過改變 結(jié)構(gòu)來實(shí)現(xiàn)。就算你通過繁瑣的方法實(shí)現(xiàn)了揩局,但有于瀏覽器的兼容性而導(dǎo)致最終效果不一致毫玖。雖然前面介紹的CSS3屬性中的box-sizing在一定程度上 解決這樣的問題,其實(shí)今天的calc()函數(shù)功能實(shí)現(xiàn)上面的效果來得更簡單凌盯。
什么是calc()?
學(xué)習(xí)calc()之前付枫,我們有必要先知道calc()是什么?只有知道了他是個(gè)什么東東驰怎?在實(shí)際運(yùn)用中更好的使用他阐滩。
calc() 從字面我們可以把他理解為一個(gè)函數(shù)function。其實(shí)calc是英文單詞calculate(計(jì)算)的縮寫县忌,是css3的一個(gè)新增的功能掂榔,用來指定元 素的長度。比如說症杏,你可以使用calc()給元素的border衅疙、margin、pading鸳慈、font-size和width等屬性設(shè)置動(dòng)態(tài)值。為何說 是動(dòng)態(tài)值呢?因?yàn)槲覀兪褂玫谋磉_(dá)式來得到的值喧伞。不過calc()最大的好處就是用在流體布局上走芋,可以通過calc()計(jì)算得到元素的寬度。
calc()能做什么潘鲫?
calc()能讓你給元素的做計(jì)算翁逞,你可以給一個(gè)div元素,使用百分比溉仑、em挖函、px和rem單位值計(jì)算出其寬度或者高度,比如說“width:calc(50% + 2em)”浊竟,這樣一來你就不用考慮元素DIV的寬度值到底是多少怨喘,而把這個(gè)煩人的任務(wù)交由瀏覽器去計(jì)算津畸。
calc()語法
calc()語法非常簡單,就像我們小時(shí)候?qū)W加 (+)必怜、減(-)肉拓、乘(*)、除(/)一樣梳庆,使用數(shù)學(xué)表達(dá)式來表示:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">.elm {
width: calc(expression);
}
</pre>
其中"expression"是一個(gè)表達(dá)式暖途,用來計(jì)算長度的表達(dá)式。
calc()的運(yùn)算規(guī)則
calc()使用通用的數(shù)學(xué)運(yùn)算規(guī)則膏执,但是也提供更智能的功能:
- 使用“+”驻售、“-”、“*” 和 “/”四則運(yùn)算更米;
- 可以使用百分比欺栗、px、em壳快、rem等單位纸巷;
- 可以混合使用各種單位進(jìn)行計(jì)算;
- 表達(dá)式中有“+”和“-”時(shí)眶痰,其前后必須要有空格瘤旨,如"widht: calc(12%+5em)"這種沒有空格的寫法是錯(cuò)誤的;
- 表達(dá)式中有“*”和“/”時(shí)竖伯,其前后可以沒有空格存哲,但建議留有空格。
瀏覽器的兼容性
瀏 覽器對calc()的兼容性還算不錯(cuò)七婴,在IE9+祟偷、FF4.0+、Chrome19+打厘、Safari6+都得到較好支持修肠,同樣需要在其前面加上各瀏覽器廠 商的識別符,不過可惜的是户盯,移動(dòng)端的瀏覽器還沒僅有“firefox for android 14.0”支持嵌施,其他的全軍覆沒。
大家在實(shí)際使用時(shí)莽鸭,同樣需要添加瀏覽器的前綴
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"> .elm {
/Firefox/
-moz-calc(expression);
/chrome safari/
-webkit-calc(expression);
/*Standard */
calc();
}
</pre>
通過上面的了解吗伤,大家對calc()不在那么陌生,但對于實(shí)際的運(yùn)用可能還是不太了解硫眨,那么大家就接下來跟我一起動(dòng)手足淆,通過實(shí)例來了解他吧。首先我們來看一個(gè)最常用的實(shí)例:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"><div class="demo">
<div class="box"></div>
</div>
</pre>
上面的結(jié)構(gòu)很簡單,就是一個(gè)div.demo的元素中包含了一個(gè)div.box的元素巧号,接下來我們一步一步來看其中的變化族奢。
第一步:添加普通樣式:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">.demo {
width: 300px;
background: #60f;
}
.box {
width: 100%;
background: #f60;
height: 50px;
}
</pre>
此時(shí)的效果很簡單,就是div.box完全遮蓋了div.demo裂逐,如下圖所示:
[圖片上傳失敗...(image-46efc9-1569579730890)]
第二步歹鱼,在div.box上添加border和padding
這一步很棘手的事情來了,在div.box上添加10px的內(nèi)距padding卜高,同時(shí)添加5px的border:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">.demo {
width: 300px;
background: #60f;
}
.box {
width: 100%;
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
}
</pre>
為了更好的說明問題弥姻,我在div.demo上添加了一個(gè)padding:3px 0;
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">.demo {
width: 300px;
background: #60f;
padding: 3px 0;
}
.box {
width: 100%;
background: #f60;
height: 50px;
padding: 10px;
border: 5px solid green;
}
</pre>
這個(gè)時(shí)候大家不知道能否想到問題會(huì)發(fā)生在哪?其實(shí)很簡單掺涛,這個(gè)時(shí)候div.box的寬度大于了其容器div.demo的總寬度庭敦,從而撐破容器伸出來了,如圖所示:
[圖片上傳失敗...(image-ee1a2e-1569579730889)]
第三步薪缆,calc()的運(yùn)用
為 了解決撐破容器的問題秧廉,以前我們只能去計(jì)算div.box的寬度,用容器寬度減去padding和border的值拣帽,但有時(shí)候疼电,我們苦于不知道元素的總寬 度,比如說是自適應(yīng)的布局减拭,只知道一個(gè)百分值蔽豺,但其他的值又是px之類的值,這就是難點(diǎn)拧粪,死卡住了修陡。隨著CSS3的出現(xiàn),其中利用box-sizing來 改變元素的盒模型類型實(shí)使實(shí)現(xiàn)效果可霎,但今天我們學(xué)習(xí)的calc()方法更是方便魄鸦。
知道總寬度是100%,在這個(gè)基礎(chǔ)上減去boder的寬度 (5px * 2 = 10px),在減去padding的寬度(10px * 2 = 20px)癣朗,即"100% - (10px + 5px) * 2 = 30px" 拾因,最終得到的值就是div.box的width值:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">.demo {
width: 300px;
background: #60f;
padding: 3px 0;
}
.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);
}
</pre>
這樣一來,通過calc()計(jì)算后旷余,div.box不在會(huì)超出其容器div.demo的寬度绢记,如圖所示:
[圖片上傳失敗...(image-7fb395-1569579730889)]
上面是一個(gè)簡單的實(shí)例,接下來我們一起來看一個(gè)自適應(yīng)布局的例子:
上面的demo是一個(gè)非常簡單而常見的布局效果荣暮,在這個(gè)布局中,我采用了自適應(yīng)布局罩驻。整個(gè)布局包含了“頭部”穗酥、“主內(nèi)容”、“邊欄”和“腳部”,并且“主內(nèi)容”居左砾跃,“邊欄”靠右骏啰,具體結(jié)構(gòu)請看DEMO中的html部分。
接下來抽高,我們主要看看css部分:
1判耕、在body中設(shè)置一個(gè)內(nèi)距,并附上一些基本的樣式翘骂,大家可以根據(jù)自己需要進(jìn)行不同的設(shè)置壁熄,此例代碼如下:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">body {
background: #E8EADD;
color: #3C323A;
padding: 20px;
}
</pre>
2、設(shè)置主容器“wrapper”的樣式
主容器的寬度是“100% - 20px * 2”,并且水平居中:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;"> .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;
}
</pre>
給不支持calc()的瀏覽器設(shè)置了一個(gè)固定寬度值“1024px”碳竟。
3草丧、給header和footer設(shè)置樣式
這個(gè)例子中的header和footer很簡單,給他們添加了一個(gè)內(nèi)距為20px莹桅,其他就是一些基本的樣式設(shè)置昌执,那么其對應(yīng)的寬度應(yīng)該是"100% - 20px * 2":
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">#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);
}
</pre>
4、給主內(nèi)容設(shè)置樣式
給主內(nèi)容設(shè)置了一個(gè)8px的邊框诈泼,20px的內(nèi)距懂拾,并且向左浮動(dòng),同時(shí)設(shè)置了一個(gè)向右的外邊距“20”px铐达,關(guān)鍵之處岖赋,我們主內(nèi)容占容器寬度的75%,這樣一來娶桦,主內(nèi)容的寬度應(yīng)該是“75% - 8px * 2 - 20px * 2”:
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">#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);
}
</pre>
4贾节、設(shè)置右邊欄樣式
給邊欄設(shè)置了一個(gè)25%的寬度,其除了包含8px的邊框衷畦,10px的內(nèi)距外栗涂,還有主內(nèi)容外距20px也要去掉,不然整個(gè)寬度與容器會(huì)相差20px,換句話說就會(huì)撐破容器掉下來祈争。因此邊欄的實(shí)際寬度應(yīng)該是"25% - 10px * 2 - 8px * 2 -20px":
<pre style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-wrap: break-word; overflow-x: auto; font-size: 16px; line-height: 28px; color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">#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);
}
</pre>
這樣一來斤程,大家就看到了上面demo展現(xiàn)的布局效果。經(jīng)過此例的學(xué)習(xí)菩混,大家是不是會(huì)覺得使用calc()用于自適應(yīng)布局是超爽的呀忿墅。此時(shí)有很多同學(xué)肯定會(huì)感吧,苦逼的IE6-8不支持沮峡,不敢使用疚脐。
原地址: https://blog.csdn.net/zxjiayou1314/article/details/44988017