挪动端页面开辟适配 rem规划道理
什么是适配,为何要适配
我们拿到的设想图平常是以640,750,1080分辨率为基准设想的,而如今的手机终端形形色色,分辨率差别,逻辑像素差别 ,视口差别,所以为了让我们的页面在每一个装备上都能够优越的展现,那末就须要为这些装备做一致的处置惩罚,这个历程就称为挪动端适配。
须要晓得的一些观点:
物理像素(physical pixel)
一个物理像素是显现器(手机屏幕)上最小的物理显现单元,能够理解为我们日常平凡说的分辨率。
装备自力像素(density-independent pixel)
装备自力像素(也叫密度无关像素),能够认为是盘算机坐标体系中得一个点,这个点代表一个能够由顺序运用的假造像素(比方: css像素),然后由相干体系转换为物理像素,在这里能够理解为我们说的视觉视口的大小;
所以说,物理像素和装备自力像素之间存在着肯定的对应关联,这就是接下来要说的装备像素比。
装备像素比(device pixel ratio)
装备像素比(简称dpr)定义了物理像素和装备自力像素的对应关联,它的值能够按以下的公式的获得:
装备像素比 = 物理像素 / 装备自力像素 // 在某一方向上,x方向或许y方向
装备像素比也是装备临盆的时刻设置好的,在javascript中,能够通window.devicePixelRatio猎取到当前装备的dpr。
视口(viewport)
pc端视口指浏览器窗口内的内容地区,不包括工具条,滚动条.
挪动浏览器中视口分为几种状况:
<metaname=”viewport”content=“width=device-width,minimum-scale=1.0,maximum-scale=1.0”/>中content所设置的视口,称为规划视口,最大值由浏览器厂商划定 ,能够document.documentElement.clientWidth猎取其宽度.
而我们看到的浏览器的窗口,网页地区的大小,称为视觉视口,用css像素示意(装备逻辑像素)
rem
rem是css3 的一个长度单元 ,相对文档跟元素 html;比方设置html font-size=100px;那末1rem=100px;以后的一切元素都能够用这个基准值来设置大小;
经常使用的计划:
牢固高度,宽度自适应(百分比,em)
运用 rem规划
下面总结了网易 淘宝首页运用rem的计划
网易的做法:
1) 将规划可口设置为视觉视口,不举行缩放,即抱负视口。
<meta name="viewport"content="initial-scale=1,maximum-scale=1, minimum-scale=1”>
2) 以设想稿分辨率为基准,取100px为font-size的参照,那末设想稿的宽假如是640,body元素的宽度就能够设置为width:6.4rem(640/100),当我们将规划视口设置为320时,因而html的font-size=deviceWidth / 6.4。
3) 经由过程document.documentElement.clientWidth猎取deviceWidth;
4) 当页面的dom ready后设置html font-size,
document.documentElement.style.fontSize =document.documentElement.clientWidth / 6.4 + ‘px’
5) 经由过程mediaQuery
设置字体大小,字体大小不能够运用rem,原因是偏差太大。
以640的设想稿为例终究的设置html font-size代码以下,规划时拿设想稿标注的尺寸除以100,就是rem的值,相称简朴啊
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';
这里if(deviceWidth > 640) deviceWidth = 640; 是因为当deviceWidth大于640时物理分辨率已大于1280(取决于dpr
),应该去接见pc的网站;
淘宝的做法:
道理
1) 经由过程dpr设置缩放比,完成规划视口大小,
var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale='+ scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
2) 动态盘算html的font-size
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + ‘px’;
这里的意义是,clientWidth / 10 获得是规划视口下的rem基准值(以iphone6为例 1rem=75px),那末设想稿恰好也是 750,所以对应的关联 clientWidth / 10==设想稿的尺寸/x, 那末x=设想稿的尺寸/rem基准值。
假如是iphone6 plus rem基准值即是clientWidth / 10 即是124.2,那末x=750/124.2。
关于详细的完成 淘宝供应了一个开源的计划lib-flexible:https://github.com/amfe/lib-f…;
详细逻辑 :
1)推断head中是不是设置了viewport,假如有设置,依据已有viewport 设置缩放比;
if (metaEl) {
console.warn('将依据已有的meta标签来设置缩放比例');
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
}
2)假如没有设置meta viewport,推断是不是设置dpr,假如有,经由过程dpr盘算缩放scale。
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);//maximum 设置最大值,与initial的值比较,取最小值;
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
3)假如 dpr &scale都没有设置,那末就经由过程装备的dpr设置起缩放 scale,
if (!dpr && !scale) {//meta[name="viewport"]&&meta[name="flexible"]都不存在。
var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下,关于2和3的屏,用2倍的计划,其他的用1倍计划
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他装备下,依旧运用1倍的计划
dpr = 1;
}
scale = 1 / dpr;
}
4)获得scale以后 ,假如meta 的viewport不存在,那末就建立一meta[name=“viewport”],将scale设置进去。
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
}
5)动态改写html的font-size
var width = docEl.getBoundingClientRect().width;//猎取html的宽度
if (width / dpr > 540) {//推断屏幕逻辑像素大于540时,取540
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
总结:
运用rem规划,本质都是经由过程动态改写html的font-size基准值,来完成差别装备下的优越一致适配;
网易与淘宝差别 的处所是 ,网易将规划视口设置成了 视觉视口,淘宝将规划视口设置成了物理像素大小,经由过程 scale缩放嵌入了 视觉视口中;
容器元素的字体大小都不运用rem,须要分外的media查询;
参考文章链接:
http://www.cnblogs.com/lyzg/p…;
http://mobile.51cto.com/web-4…