自適應開發——rem

摘要: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);

接下來就可以開心的寫代碼了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章