REM 布局是利用 css 中的 rem 单位来进行布局, 前面对 viewport 的 width 设置了固定的宽度来进行布局, 这个有个弊端就是页面做得太死, 不利于自适应

rem 是基于页面跟元素进行大小设置的。如果我们把页面的跟元素大小设置好后, 就能控制页面中的每一元素的大小了。看下图

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>rem 布局</title>
	<style type="text/css">
		html{
			font-size: 40px;
		}
		p{
			font-size: 1rem;
		}
	</style>
</head>
<body>
	<p>Rem 布局学习</p>
</body>
</html>


从上面可看到 p 标签的字体大小最终的渲染结果为 40px, 这个是根据 1rem = 跟元素的 font-size 来的, 这里的跟元素的 font-size 等于 40px 所以 p 元素的字体就等于 1 * 40 = 40px。

如何自适应?

到这里我们会遇到另一个问题 : 各手机的屏幕大小不同, 如何做到在大屏的手机上 40px 的字体显示大一些, 小屏的手机上显示小一些, 如何做到自适应?

我们参照 iphone5 手机大小来做, iphone5 的屏幕宽度是 320px, 但是开发中设计稿通常是 640px, 因为 iphone 是双倍屏。假如我们把 html 的 font-size 设置为 100px, 那么 body 元素的宽度为 6.4rem (100px * 6.4 = 640px)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Rem</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/>
	<style type="text/css">
		html{
			font-size: 100px;
		}
		body{
			width: 6.4rem;
			font-size: 0.2rem;
		}
	</style>
</head>
<body>
	<script type="text/javascript">
		var width = document.getElementsByTagName("body")[0].clientWidth;
		document.write("body 的宽度为 : "+width+"px");
	</script>
	<br/>
	<span>
		字体大小为 20px (0.2 * 100px = 20px)
	</span>
</body>
</html>
到这里还有一些问题, html 的宽度为 device-width(设备宽度), 而 body 的宽度是 640px 给固定了。假如 html 中的宽度等于 device-width, 目前我们知道 body 的宽度为 640px 是不是就能反推出 html 的宽度了?

6.4 * 100px = 640px 假设这个 640 等于 device-width
如果我们能拿到 device-width 的值, 是不是就可以动态的计算出 html 的 font-size

document.documentElement.clientWidth / 6.4 = html font-size

获取到浏览器视窗的宽度然后除以 6.4 这个已知的比例值就能得道 html 的 font-size, 因为不同设备的 device-width 不同, 得到的 font-size 也会不同, 同时 body 的宽度也会与 device-width 相同, 这个时候就能自适应了。

我们假设设计稿宽度是与用户手机设备的宽度一样那么就有下面的关系
设备宽度与设计稿的尺寸成正比宽度一样

document.documentElement.clientWidth / 640 = 1

前面我们以 100px 为 html 的 font size, 就有下面的公式

fontsize = (document.documentElement.clientWidth / 640) * 100;

这里当用户手机设备屏幕宽度很大时得到的 fontsize 就越大,反之久很小,可以自适应所有设备	
利用设计稿 640 宽度 与 设备宽度的比例 拿 100 基数 求 font-size
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Rem</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/>
	<style type="text/css">
		body{
			width: 6.4rem;
			font-size: 0.32rem; /* iphon5 中为 16px */
		}
	</style>
	<script>
		function resize(){
			//获取 device-width
			var clientWidth = (document.documentElement || document.body).clientWidth;
			var htmlDom = document.getElementsByTagName("html")[0];
			// 公式换算
			// 公式   倒推求 font-size
			// htmlDom.style.fontSize = (clientWidth / 6.4) + "px";
			// 公式   正推得 font-size
			// 利用设计稿 640 宽度  设备宽度的比例  100 基数  font-size
			htmlDom.style.fontSize = 100 * (clientWidth / 640) + "px";
		}
		+function() {
			resize();
		}();
	</script>
</head>
<body>
	<div id="main"></div>
	<script>
		+function(){
			function main(){
				var width = document.getElementsByTagName("body")[0].clientWidth;
				document.getElementById("main").innerHTML = "body 的宽度为 : "+width+"px";
			}
			main();
			//监听 onresize
			window.addEventListener("resize", function(){
				resize();
				main();
			});
		}();
	</script>
</body>
</html>
到这里最简单的 rem 布局就完了, 主要是使用 rem 的优点想对跟元素来进行大小设置, 使用 device-width 对 html 的 font-size 进行计算, 不同设备能得道不同的 font-size, 从而进行开发, 做到自适应。