摘要:rem 是相對於 html 的 font-size,只需要確定了 html 的 font-size 的 px 字號,就可以計算出元素的寬高。
什麼是 rem
首先大家應該知道 em 單位,em 指的是相對於父元素的字體大小的單位,而 rem 指的是相對於 html 的字體大小的單位。例如:html 的 font-size 值爲 10px ,那麼 1rem 代表的就是 10px,2rem 代表的就是 20px。
目前主要的佈局方式
1.流式佈局
流式佈局的方式,是將寬度設置成百分比,高度採用 px 固定高度,主要案例如:亞馬遜、攜程。雖然這種方式可以讓各種屏幕都適配,但是現實的效果非常差,在大屏幕手機下頁面元素會被拉長,只有部分手機可以較好的呈現設計圖效果。
2.固定寬度
早期有些頁面寫成了固定寬度,超出的部分留白,這種方式的弊端在於大屏幕手機下頁面會顯得非常小,而且白邊也不好看,不符合現在人們的審美。
3.響應式佈局
採用響應式配合媒體查詢的方法,可以在不同屏幕尺寸下呈現出不同的頁面效果,的確是很不錯,但是缺點在於開發成本較大,相當於要開發多套頁面,只能在小項目上使用,如果是大型項目的話,感覺是划不來的。
4.rem 等比例佈局
rem 能夠在不同的屏幕尺寸下顯示等比例的頁面,我認爲是既滿足需求又省力的做法。
rem 的原理
說了這麼多,該說說 rem 的工作原理了。
html{
font-size: 10px;
}
div{
width: 10rem;
height: 5rem;
background: skyblue;
color: #000000;
text-align: center;
line-height: 5rem;
font-size: 1.2rem;
}
效果如下圖:
此時 1rem = 10px。
接下來我們改變 html 的 font-size 爲 20px。
效果如下圖:
在寬高的rem值沒有變的情況下,我們只改變了 html 的 font-size 值,就改變了元素的大小。
此時的 1rem = 20px。
由此我們得出方法,通過媒體查詢,在不同屏幕尺寸情況下,設置不同的 html 的 font-size 值就可以調節rem大小。但是屏幕尺寸這麼多,我們不能一個一個的設置吧,於是想到了用 js 來設置。
//designWidth:設計稿的實際寬度值,需要根據實際設置
//maxWidth:製作稿的最大寬度值,需要根據實際設置
//這段js的最後面有兩個參數記得要設置,一個爲設計稿實際寬度,一個爲製作稿最大寬度,例如設計稿爲750,最大寬度爲750,則爲(750,750)
;(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 設置好後才能執行 refreshRem,不然 refreshRem 會執行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止執行兩次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 瀏覽器後退的時候重新計算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
接下來就可以開心的寫代碼了。