1.rem适配原理
首先清除一下默认样式,这个基本上所有写H5的都通用
a,
input,
button {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
input,
button {
-webkit-appearance: none;
border-radius: 0;
}
body {
margin: 0;
-webkit-user-select: none;
}
body * {
-webkit-user-select: none;
font-family: Helvetica;
}
body {
-webkit-text-size-adjust: 100%;
}
h1 {
margin: 0;
}
a {
text-decoration: none;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
img {
vertical-align: top;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
现在我们看看如何使用rem解决适配问题
rem vs em (rem的r代表root)
rem 是相对根节点的字体大小进行计算的
em 是相对长度单位。相对于当前对象内文本的字体尺寸。
所以,rem的关键是根结点的字体大小
<script>
(function(){
var html = document.documentElement;
var hWidth = html.getBoundingClientRect().width; //拿到html的宽度。打印出来是320
// 320/16 = 20 所以1rem = 20px
// 因为此处除以16,所以16rem刚好把屏幕占满
html.style.fontSize = hWidth/16 + "px";
// 那么80px === 4rem
})()
</script>
接下来看一下完整的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,user-scalable=no"/>
<title></title>
<script>
(function(){
var html = document.documentElement;
var hWidth = html.getBoundingClientRect().width; //拿到html的宽度。打印出来是320
// 320/16 = 20 所以1rem = 20px
// 因为此处除以16,所以16rem刚好把屏幕占满
html.style.fontSize = hWidth/16 + "px";
// 那么80px === 4rem
})()
</script>
<style>
body{
margin: 0;
}
div{
float: left;
box-sizing: border-box;
width: 4rem; //此处之前写的是80px,转换成就是4rem
height: 4rem; //此处之前写的是80px,转换成就是4rem
border: 1px solid #000;
}
div:nth-of-type(1){
background-color: red;
}
div:nth-of-type(2){
background-color: yellow;
}
div:nth-of-type(3){
background-color: green;
}
div:nth-of-type(4){
background-color: pink;
}
</style>
</head>
<body>
<!--
rem / em
rem的r代表root rem是相对根节点的字体大小进行计算的
em 是相对长度单位。相对于当前对象内文本的字体尺寸。
-->
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>
看到这里相信很多人和我一样还是云里雾里,没关系,继续往下看。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,user-scalable=no"/>
<title></title>
<script>
(function(){
var html = document.documentElement;
var hWidth = html.getBoundingClientRect().width;
html.style.fontSize = hWidth/15 + "px"; //font-size ==》
})()
// 给的设计稿w = 750px
// 所以量出来var hWidth = html.getBoundingClientRect().width === 750
// 750/15 = 50 也就是把这个屏幕平分成15份,font-size = 50px 1rem = 50px
// 那么开发的时候,假如在设计稿中量出来一个103px,那么就在css中写成103/50 = 2.06rem就好了
// 那么问题来了,每一次从px转成rem是不是还要用计算器去除一下,很多人推荐了koala这个工具,
// 自动把px可以转成rem。现在vscode有了相应的插件cssrem。
</script>
<link rel="stylesheet" type="text/css" href="bs/css/bootstrap.css"/>
<link rel="stylesheet" href="css/index.css" />
</head>
其实这个界面已经实现了适配。具体代码可以在我的github中去下载。https://github.com/JiaojSun(h5basic)
有人可能觉得这个做法怎么和网上说的大多数适配不太一样,其实原理是一样的,只是理解起来更简单,现在看看网易的做法。
document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
这个6.4怎么来的,当然是根据设计稿的横向分辨率/100得来的。下面总结下网易的这种做法:
先拿设计稿竖着的横向分辨率除以100得到body元素的宽度:
如果设计稿基于iphone6,横向分辨率为750,body的width为750 / 100 = 7.5rem 如果设计稿基于iphone4/5,横向分辨率为640,body的width为640 / 100 = 6.4rem
所以这个是6.4还是7.5是看你的设计稿的。这样的话px=>rem 只需要除以100而不是50这样纯粹是为了好计算。
有一篇博文写的非常好,推荐看看从网易与淘宝的font-size思考前端设计稿与工作流
2.rem使用
总结一下,假如你初次j接触移动端h5,来不及看上面的原理,那么直接引入下面代码,然后设计稿中有个宽度是109px,那么你直接写成1.09rem。(前提是设计稿是750px哦,如果设计稿是375那么7.5也要改)
<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<script>(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = clientWidth / 7.5 + 'px';
};
// Abort if browser does not support addEventListener
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
以上已经把移动端适配讲的清清楚楚了。
当然还有其他的方式,以后再说,这个已经足以解决工作中的困惑了!