自适应开发——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);

接下来就可以开心的写代码了。

猜你喜欢

转载自my.oschina.net/u/3026577/blog/1647995