移动端(手机端)页面自适应解决方案—rem布局

假设设计妹妹给我们的设计稿尺寸为750 * 1340。结合网易、淘宝移动端首页html元素上的动态font-size属性、设计稿尺寸、前端与设计之间协作流程一般分为下面两种:

一、网易做法:

引入:页面开头处引入下面这段代码,用于动态计算font-size

(function(doc, win) {
var docEl = doc.documentElement,
isIOS = navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
dpr = isIOS ? Math.min(win.devicePixelRatio, 3) : 1,
dpr = window.top === window.self ? dpr : 1, //被iframe引用时,禁止缩放
dpr = 1,
scale = 1 / dpr,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
docEl.dataset.dpr = dpr;
var metaEl = doc.createElement('meta');
metaEl.name = 'viewport';
metaEl.content = 'initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale;
docEl.firstElementChild.appendChild(metaEl);
var recalc = function() {
var width = docEl.clientWidth;
if (width / dpr > 750) {
width = 750 * dpr;
}
// 乘以100,px : rem = 100 : 1
docEl.style.fontSize = 100 * (width / 750) + 'px';
};
recalc()
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
})(document, window);

使用:

未引入前:

body {
width: 750px;
height: 640px;
}

引入后:除以100并将px换成rem

body {
width: 7.5rem;
height: 6.4rem;
}

换算的依据:

// 乘以100,px : rem = 100 : 1
var recalc = function() {
var width = docEl.clientWidth;
if (width / dpr > 750) {
width = 750 * dpr;
}
// 乘以100,px : rem = 100 : 1
docEl.style.fontSize = 100 * (width / 750) + 'px';
};

二、淘宝做法(推荐做法,尤其是app内嵌页面):

引入:页面开头处引入下面这段代码,用于动态计算font-size,或者单独放入一个文件,引入文件也可以

;
(function(win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {}); if (metaEl) {
var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
} if (!dpr && !scale) {
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;
} docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
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);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
} function refreshRem() {
var width = docEl.getBoundingClientRect().width;
// 适配平板
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
} 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 = 12 * dpr + 'px';
} else {
doc.addEventListener('DOMContentLoaded', function(e) {
doc.body.style.fontSize = 12 * dpr + 'px';
}, false);
} refreshRem(); flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function(d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
}
flexible.px2rem = function(d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
} })(window, window['lib'] || (window['lib'] = {}));

使用:

未引入前:

body {
width: 750px;
height: 640px;
}

引入后:

@font-size-base: 75;
body {
width: 750rem/@font-size-base;
height: 640rem/@font-size-base;
}

换算依据:

function refreshRem() {
var width = docEl.getBoundingClientRect().width;
// 适配平板
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}

这边是用的less,如果您没有用less,就需要手动计算,当然也可以转化为px : rem = 100 : 1。
如果想转化为px : rem = 100 : 1,可以修改上面的refreshRem函数:

function refreshRem() {
var width = docEl.getBoundingClientRect().width
// 适配平板
if (width / dpr > 750) {
width = 750 * dpr
}
var rem = 100 * (width / 750)
docEl.style.fontSize = rem + 'px'
flexible.rem = win.rem = rem;
}

使用:

未引入前:

body {
width: 750px;
height: 640px;
}

引入后:除以100并将px换成rem

body {
width: 7.5rem;
height: 6.4rem;
}

换算依据就是上面修改的代码:

function refreshRem() {
var width = docEl.getBoundingClientRect().width
// 适配平板
if (width / dpr > 750) {
width = 750 * dpr
}
var rem = 100 * (width / 750)
docEl.style.fontSize = rem + 'px'
flexible.rem = win.rem = rem;
}

具体实现原理请参照:从网易与淘宝的font-size思考前端设计稿与工作流,写的很不错!

希望对需要的朋友有所帮助!

原文地址:https://segmentfault.com/a/1190000012225828

移动端(手机端)页面自适应解决方案—rem布局篇的更多相关文章

  1. 手机端页面自适应解决方案—rem布局进阶版

    手机端页面自适应解决方案—rem布局进阶版   https://www.jianshu.com/p/985d26b40199 注:本文转载之处:https://www.cnblogs.com/anni ...

  2. 手机端页面自适应解决方案—rem布局(进阶版,附源码示例)

    转自:https://segmentfault.com/a/1190000007350680 一年前笔者写了一篇 <手机端页面自适应解决方案—rem布局>,意外受到很多朋友的关注和喜欢.但 ...

  3. 手机端页面自适应解决方案—rem布局(该方案目前已过时)

    转自:https://segmentfault.com/a/1190000004705207 相信很多刚开始写移动端页面的同学都要面对页面自适应的问题,当然解决方案很多,比如:百分比布局,弹性布局fl ...

  4. 手机端页面自适应解决方案-rem布局

    rem布局 布局前插入原生js即可 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationch ...

  5. 手机端页面自适应解决方案—rem布局

    只需在页面引入这段原生js代码就可以了 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientation ...

  6. 70.JS---利用原生js做手机端网页自适应解决方案rem布局

    利用原生js做手机端网页自适应解决方案rem布局 刚开始我用的是下面这段代码,然后js通过外部链接引入,最后每次用手机刷新网页的时候都会出现缩略图 function getRem(pwidth, pr ...

  7. 手机端页面自适应:rem布局

    rem布局非常简单,首页你只需在页面引入这段原生js代码就可以了 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = ...

  8. 手机端页面自适应之rem布局

    W3C官网上是这样描述rem的--"font size of the root element" . rem布局在移动端发挥的比较好. 阿里团队高清方案: <script&g ...

  9. 移动端(手机端)页面自适应解决方案1(rem布局)---750设计稿

    设计稿尺寸为750 * 1340.结合网易.淘宝移动端首页html元素上的动态font-size属性.设计稿尺寸.前端与设计之间协作流程一般分为下面两种: 网易做法: 页面开头处引入下面这段代码,用于 ...

随机推荐

  1. [转]Adobe CC 2018 下载链接 Creative Cloud 2018 - Creative Cloud 2018 – Adobe CC 2018 Download Links

    Creative Cloud 2018 – Adobe CC 2018 Download Links – ALL Languages Adobe CC 2018Direct Downloads Win ...

  2. SpringBoot学习笔记(15)----SpringBoot使用Druid

    直接访问Druid官网wiki,有详细教程,地址如下: SpringBoot支持Druid地址:https://github.com/alibaba/druid/tree/master/druid-s ...

  3. 我的Java历程_Java对象类型的转换

    向上转型: 可以将子类对象看作是父类对象叫做“向上转型”,由于向上转型是从一个较为具体的类向较为抽象的类的转换,所以它总是安全的. 例如:可以将正方形.长方形叫做是四边形,但是不能说四边形是正方形或长 ...

  4. Msql免安装版安装

     文首提要:             我下载的MySQL版本是:mysql-5.7.17-winx64.zip  Archive版:系统:Windows7 64位. 一.解压文件 下载好MySQL后, ...

  5. POJ-1511 Invitation Cards 往返最短路 邻接表 大量数据下的处理方法

    题目链接:https://cn.vjudge.net/problem/POJ-1511 题意 给出一个图 求从节点1到任意节点的往返路程和 思路 没有考虑稀疏图,上手给了一个Dijsktra(按紫书上 ...

  6. 洛谷 P4932 浏览器 (思维题)

    题目大意:给你一个序列,求满足$x_{i}\: xor\; x_{j}$在二进制下1的数量为奇数的数对数量 打月赛的时候真没想出来,还是我太弱.. xor意义下,对于两个数,假设它们两个每一位都是2个 ...

  7. Vue中如何监控某个属性值的变化?

    比如现在需要监控data中, obj.a 的变化.Vue中监控对象属性的变化你可以这样: deep属性表示深层遍历,但是这么写会监控obj的所有属性变化,并不是我们想要的效果,所以做点修改: 还有一种 ...

  8. LaTeX 表格

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50066137 一些LaTeX中表格的使 ...

  9. 【转】Hook钩子C#实例

    [转]Hook钩子C#实例 转过来的文章,出处已经不知道了,但只这篇步骤比较清晰,就贴出来了. 一.写在最前 本文的内容只想以最通俗的语言说明钩子的使用方法,具体到钩子的详细介绍可以参照下面的网址: ...

  10. JAVA关于byte数组与String转换的问题

    1 public class ToString{ public static void main(String[] args){ String aa = "hellow"; byt ...