前言
在自適應(yīng)布局或者移動(dòng)端網(wǎng)頁(yè)開(kāi)發(fā)時(shí),我們經(jīng)常會(huì)用到em和rem兩個(gè)長(zhǎng)度單位。接下來(lái)我們討論一下這兩個(gè)單位和px之間的區(qū)別,以及他們的使用場(chǎng)景等。
區(qū)別
px
px,像素(計(jì)算機(jī)屏幕上的一個(gè)點(diǎn))。(引自w3school-css單位)
像素(Pixels),相對(duì)長(zhǎng)度單位,它是相對(duì)于顯示器屏幕分辨率而言的,它兼容性好而且精確,但是這種方法當(dāng)用戶在縮放瀏覽器或者需要兼容不同移動(dòng)設(shè)備時(shí),我們的頁(yè)面布局可能會(huì)被打破。?
em
em為了解決上述問(wèn)題而進(jìn)化產(chǎn)生,也是相對(duì)長(zhǎng)度單位,根據(jù)使用它的元素的大小決定(有人誤以為是根據(jù)父元素,那是因?yàn)槭褂盟脑乩^承了父類的屬性,根據(jù)W3C標(biāo)準(zhǔn)可知 ,它們是基于當(dāng)前對(duì)象元素的字體大?。?,它可以自動(dòng)適應(yīng)用戶所使用的字體。
em,相對(duì)長(zhǎng)度單位。相對(duì)于當(dāng)前對(duì)象內(nèi)文本的字體尺寸。
如當(dāng)前對(duì)行內(nèi)文本的字體尺寸未被人為設(shè)置,則相對(duì)于瀏覽器的默認(rèn)字體尺寸。(引自em-CSS3參考手冊(cè))
關(guān)于em值的計(jì)算
假設(shè)任意瀏覽器的默認(rèn)字體大小都是16px。所有未經(jīng)調(diào)整的瀏覽器中都是1em=16px。為了方便換算,我們通常在css中設(shè)置body的屬性 font-size:62.5%,這就使1em值變?yōu)?0px,這樣我們就可以把設(shè)計(jì)稿的px值除以10,然后換上em作為單位來(lái)進(jìn)行px和em的換算,十分簡(jiǎn)單,例如16px可以改寫為1.6em。
rem
由于em值不是固定的,1em在不同元素下的值會(huì)因?yàn)樵撛鼗蛘咴撛馗冈氐拇笮〔煌煌虼嗽谖覀兌啻问褂脮r(shí),就會(huì)帶來(lái)開(kāi)發(fā)的難度。這時(shí)候rem(root em)應(yīng)運(yùn)而生了。rem是相對(duì)于根(html)元素,這就意味著,我們只需要根據(jù)自己的需要給根元素確定一個(gè)參考值,然后通過(guò)它既可以做到只修改根元素就成比例地調(diào)整所有字體大小,又可以避免字體大小逐層復(fù)合的連鎖反應(yīng)。最大的優(yōu)點(diǎn)是提供一致尺寸,便于計(jì)算。
rem,相對(duì)長(zhǎng)度單位。相對(duì)于根元素(即html元素)font-size計(jì)算值的倍數(shù)。(引自rem-CSS3參考手冊(cè))
根元素重寫
em 和 rem 單位之間的區(qū)別是瀏覽器根據(jù)誰(shuí)來(lái)轉(zhuǎn)化成px值,em是基于當(dāng)前對(duì)象內(nèi)文本的字體尺寸決定,rem是基于html元素的字體大小來(lái)決定,而根(html)元素的字體大小如果沒(méi)有顯式地設(shè)置固定值去覆蓋,那么它首先來(lái)自瀏覽器設(shè)置,因此瀏覽器的字體大小設(shè)置可以影響每個(gè)使用rem單元以及每個(gè)通過(guò)em單位繼承的值。為了還原設(shè)計(jì)稿和實(shí)現(xiàn)合理的布局所以需要根元素重寫。瀏覽器縮放動(dòng)態(tài)修改根元素大小可以參考以下代碼段。
<script>
var timer, style = document.head.appendChild(document.createElement("style"));
var useREM = window.useREM = Object.create({
resize: function () {
var config=this.config;
this.size=Math.max(config.min, Math.min(config.max, document.documentElement.clientWidth)) / config.num;
style.innerHTML="html{font-size: "+ this.size +"px !important;}"
return this;
},
set: function (newConfig) {
if(newConfig){
for (var a in newConfig){
if(this.config.hasOwnProperty(a)){
this.config[a]=newConfig[a];
}
}
}
this.resize();
return this;
}
}, {
size: {
value: 20,
writable: true,
configurable: false,
enumerable: true
},
config: {
value:{
max: 1200,//設(shè)置最大可視區(qū)寬
min: 900,//設(shè)置最小可視區(qū)寬
num: 10,//根據(jù)需求調(diào)整比例
delay: 100
},
writable: false,
configurable: false,
enumerable: true
}
});
addEventListener("resize", function () {
clearTimeout(timer);
timer = setTimeout(this.resize.bind(this), this.config.delay);
}.bind(useREM));
useREM.set();
</script>
同時(shí),也有人認(rèn)為這種做法在一定程度上剝奪了用戶對(duì)瀏覽器字體設(shè)置的權(quán)利,他們的觀點(diǎn)是rem的好處是給了我們的一個(gè)途經(jīng)去獲取用戶的偏好來(lái)影響網(wǎng)站中每一處使用rem的元素大小,無(wú)論用戶如何設(shè)置自己的瀏覽器,我們的布局都能調(diào)整到合適大小。這個(gè)就暫不做討論吧,日后有機(jī)會(huì)再講。
使用場(chǎng)景
- 如果這個(gè)屬性根據(jù)它的font-size進(jìn)行測(cè)量,則使用em,其他的使用rem
- 媒體查詢中使用 rem 單位
- 不要在多列布局中使用 em 或 rem -改用 %
關(guān)于em和rem在完成模塊化組件中的應(yīng)用實(shí)例,你可以參考這篇文章。
兼容
- 所有瀏覽器都支持px,除了IE8及以下版本,其它的瀏覽器都支持em和rem屬性。對(duì)于不支持它的瀏覽器,就多寫一個(gè)絕對(duì)單位的聲明。
- IE9/IE10在用于偽元素時(shí)或者使用字體簡(jiǎn)寫聲明時(shí)不支持rem
- IOS Safari5.0-5.1雖然支持rem,但是在使用媒體查詢時(shí)不支持rem
工具
在這里為大家提供一個(gè)px,em,rem單位轉(zhuǎn)換工具。地址:http://pxtoem.com/
討論區(qū)
- csdn移動(dòng)端和pc端兩套代碼,兩種字號(hào)大小聲明,pc端用了px,沒(méi)有根據(jù)瀏覽器縮放自適應(yīng),移動(dòng)端用了rem,根據(jù)屏幕寬度重寫了根元素,實(shí)現(xiàn)了自適應(yīng)。
- 掘金主頁(yè)用了rem,在mac的chrome中根元素固定12px,但是文字大小有根據(jù)瀏覽器縮放實(shí)現(xiàn)自適應(yīng)。
- 你們團(tuán)隊(duì)是怎么做的?