涉及到的一些名词, 详细解释可参考 移动端适配前篇--移动端适配 rem

名词解释

【英寸Inch】英寸表示屏幕斜对角线的长度

【像素Pixel】像素是图像的基本采样单位,它不是一个确定的物理量,因为像素点的物理大小是不确定的

【分辨率】分辨率是屏幕像素的数量,一般用屏幕宽度的像素点乘以屏幕高度的像素点。如描述iphone6的分辨率是750*1334.

分辨率又分为【物理分辨率】和【逻辑分辨率】,值得注意的是实际工作中设计师常常给的是物理分辨率,程序中用到的是逻辑分辨率,但是都称为分辨率,容易混淆。

【物理分辨率】是硬件所支持的分辨率,【逻辑分辨率】是软件可以达到的分辨率。

【像素倍率dpr】物理分辨率和逻辑分辨率的商,即常说的几倍屏。

如:iphone6的分辨率写着375*667,指的是逻辑分辨率;750*1334则是它的物理分辨率,dpr=2。

使用rem适配,目前最流行的两种方式:分别是网易和手淘的做法

网易

设备逻辑像素 device-width = 设备物理像素 /(devicePixelRatio * scale)

设备物理像素: iphone6 = 750px

设备逻辑像素: iphone6 = 750/(2 * 1) = 375px

document.documentElement.clientWidth === 设备逻辑像素

body-width(rem为单位) = 设计稿宽度/100 = 640 / 100 = 6.4 rem 【取100,主要为了容易计算】

html font-size(px为单位) = device-width / body-width = 320 / 6.4 = 50 px

【步骤】

(1)视口设置:<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, minimum-scale=1">

(2)先拿设计稿竖着的横向分辨率除以100得到body元素的宽度:

如果设计稿基于iphone6,横向分辨率为750,body的width为750 / 100 = 7.5rem

如果设计稿基于iphone4/5,横向分辨率为640,body的width为640 / 100 = 6.4rem

(3)布局时,设计图标注的尺寸除以100得到css中的尺寸

设计稿150px的宽度,代码为 150/100 rem

(4)在dom ready以后,通过以下代码设置html的font-size:

document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';

【html的font-size的值 是根据设备改变而改变的】

(注:6.4是设计稿基于iphone4/5,如果是750的设计稿,应该除以7.5)

(5)font-size可能需要额外的媒介查询,并且font-size不能使用rem【此处的px是指设备逻辑像素】

@media screen and (max-width:321px){
.m-navlist{font-size:15px}
} @media screen and (min-width:321px) and (max-width:400px){
.m-navlist{font-size:16px}
} @media screen and (min-width:400px){
.m-navlist{font-size:18px}
}

【注意】最大宽度限制 设备逻辑像素宽度640 =》设备物理像素宽度1280 相当于pc端

var deviceWidth = document.documentElement.clientWidth;

if(deviceWidth > 640) deviceWidth = 640;

document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px'; 【此处6.4,由于网易以iPhone4/5,物理像素为640 * 1136

前提:假如以iPhone6/7/8为设计稿,宽度为150的元素

在 iphone6/7/8中:
由于【dpr = 2】,该元素的逻辑像素 = 150 / 2 = 75 px
html-fontSize = 375 / 7.5 = 50 px
该元素的 width = 150 / 100 = 1.5 rem
该元素的逻辑像素 / html-fontSize = 75 / 50 = 1.5 在iPhone4/5中:【逆推】
在 iphone4/5中,html-fontSize = 320 / 7.5 = 42.67 px
该元素的 width = 1.5 rem
该元素的逻辑像素 = html-fontSize * 该元素的 width(rem) = 42.67 * 1.5 = 64 px
由于【dpr = 2】,该元素的物理像素 = 逻辑像素 * dpr = 64 * 2 = 128 (即该元素的宽为128)
该元素的逻辑像素 / html-fontSize = 64 / 42.67 = 1.5 **总结:
64/320 = 75/375 = 0.2 相当于百分比适配,该元素占整屏宽度的20%**

demo:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端适配</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<style>
/* vw + rem */
html{font-size:13.33333333vw}
.box {
width: 1.5rem;
height: 1.5rem;
background-color: #ccc;
font-size: 0.24rem;
} /* rem 网易*/
.box {
width: 1.5rem;
height: 1.5rem;
background-color: #ccc;
font-size: 14px;
} /*逻辑像素*/
@media screen and (max-width:321px){
.box{font-size:15px}
} @media screen and (min-width:321px) and (max-width:400px){
.box{font-size:16px}
} @media screen and (min-width:400px){
.box{font-size:18px}
}
</style>
<script>
window.onload = function () {
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
}
</script>
</head>
<body>
<div class="box">
oooo
</div>
</body>
</html>

手淘:可使用 lib-flexible

(1)动态设置viewport的scale

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';

(3)布局的时候,各元素的css尺寸 = 设计稿标注尺寸/(设计稿横向分辨率 / 10)

(4)font-size可能需要额外的媒介查询,并且font-size不使用rem,这一点跟网易是一样的。

总结:

设备逻辑像素 device-width = 设备物理像素 /(devicePixelRatio * scale)
由于 scale = 1 / devicePixelRatio,所以【设备逻辑像素 = 设备物理像素】
前提:假如以iPhone6/7/8为设计稿,宽度为150的元素

在 iphone6/7/8中:
设备逻辑像素 = 750 /(`2*0.5`) = 750 px
由于【dpr = 2】,该元素的逻辑像素 = 150 /(`2*0.5`) = 150 px
html-fontSize = 750 / 10 = 75 px
该元素的 width(rem) = 150 / html-fontSize = 150 / 75 = 2 rem 在iPhone4/5中:【逆推】
在 iphone4/5中,html-fontSize = 640 / 10 = 64 px
该元素的 width = 2 rem
该元素的逻辑像素 = html-fontSize * 该元素的 width(rem) = 64 * 2 = 128 px => 150 / 750 = 128 / 640 = 0.2
var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

demo:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端适配</title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/> -->
<meta name="viewport"/>
<style>
.box {
width: 2rem;
height: 2rem;
background-color: #ccc;
font-size: 14px;
} /*逻辑像素*/
@media screen and (max-width:321px){
.box{font-size:15px}
} @media screen and (min-width:321px) and (max-width:400px){
.box{font-size:16px}
} @media screen and (min-width:400px){
.box{font-size:18px}
}
</style>
<script>
window.onload = function () {
var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
// console.log(document.documentElement.clientWidth) // 750 = 750 / (2 * 0.5)
// 设备逻辑像素 device-width = 设备物理像素 /(devicePixelRatio * scale)
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px'; }
</script>
</head>
<body>
<div class="box">
oooo
</div>
</body>
</html>

vw + rem

html{font-size:13.33333333vw}
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

1vw表示1%的屏幕宽度, 即屏幕宽度被分为100份vw

width:1rem 的div 就是50px* 50px (iphone6为2倍屏,即对应750px设计稿上的100px*100px)

7.5 rem = 100vw = 750px 设计稿 =》1px = 0.1333333vw =》 100px = 13.33333vw => 100px = 1rem

以iPhone6/7/8为设计稿标准, 宽度为 180 px

该元素的宽度(rem)= 180 / 100 = 1.8 rem

最后

布局时各元素的尺寸值都是根据设计稿标注的尺寸计算出来,由于html的font-size是动态调整的,所以能够做到不同分辨率下页面布局呈现等比变化

总结

经过正反推算,发现各种单位适配本质上对应着还是根据手机屏幕尺寸基于百分比进行缩放

参考:

最简单的移动端适配方案(rem+vw)

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

移动前端自适应适配布局解决方案和比较

移动端适配 后篇(rem+vm)的更多相关文章

  1. 移动端适配方案(rem+flex)

    为什么用rem不用px? 主流:各大网站的移动版绝大多数都是用的rem.   移动端屏幕分辨率差别太大:最低适配的iPhone6,分辨率仅为750*1334.而现在市面上大多数手机,都达到了1080* ...

  2. 移动端适配方案以及rem和px之间的转换

    背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿. 对于移动端开发而言,为了做到页面高清的效果,视觉稿的规范 ...

  3. pc端与移动端适配解决方案之rem

    使用方式: 在html页面开头,引入下面的原生js代码 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'ori ...

  4. 移动端适配-rem(新)

    概念 对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 移动端像素 设备像素(dp),也叫物理像素.指设备能控制显示的最小物理单 ...

  5. 移动端适配单位rem

    0 写在前面 本周惊喜地发现,其他各个老师的软工班(罗杰老师班和欧阳老师班)的软工项目的alpha版本都已经发布了!(然而我们软工项目还没开始写代码…逃…) 十分好奇的我第一时间下载了一些他们的产品进 ...

  6. 移动端适配 rem

    前置知识: 物理像素(physical pixel,device pixel) 物理像素(设备像素),显示设备中一个最微小的物理部件.每个像素可以根据操作系统设置自己的颜色和亮度. 设备独立像素(de ...

  7. 浅谈移动端适配-rem

    对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 一. 移动端开发有关于像素的概念: 1.设备像素(dp),也叫物理像素.指设备 ...

  8. 小tips:使用rem+vw实现简单的移动端适配

    首先设置meta属性,如下代码: <meta name="viewport" content="width=device-width, initial-scale= ...

  9. rem移动端适配方案

    一. rem vs em 单位 定义 特点 rem font size of the root element 以根元素字体大小为基准 em font size of the element 以父元素 ...

随机推荐

  1. gradle 离线模式offline 用法

    1. 离线模式 offline所谓离线模式offline,就是gradle在解析依赖的时候采用本地的依赖库(如 GRADLE_USER_HOME指定的路径),而不是依据项目build.gradle文件 ...

  2. json -- fastjson如何序列化@Transient的字段

    今天把fastjson包改成了1.2.58,发现@Transient标注的字段序列化后不见了,但是项目需要把@Transient字段序列化,处理方法: 原文:https://github.com/al ...

  3. Jenkins pipeline+Maven+Gitlab

    参照文档:http://www.cnblogs.com/xiaodai12138/p/9996995.html

  4. js获取当天时间,7天前后时间,时间格式化

    格式化时间年月日时分秒 //时间戳转换方法 date:时间戳数字 formatDate(date) { var date = new Date(date); var YY = date.getFull ...

  5. 【HANA系列】SAP ECLIPSE中创建ABAP项目的步骤

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP ECLIPSE中创建AB ...

  6. Linux vim文件编辑器使用

    学习目标: 通过本实验熟练vim的使用. 步骤: 1.将用户家目录的ls结果重定向到vimfile.txt 2.查看rh124第403页实验要求,并完成 参考命令: 复制文件前,需要先建立文件,教材上 ...

  7. SVM的推导和理解

    主要记录了SVM思想的理解,关键环节的推导过程,主要是作为准备面试的需要. 1.准备知识-点到直线距离 点\(x_0\)到超平面(直线)\(w^Tx+b=0\)的距离,可通过如下公式计算: \[ d ...

  8. python map 的用法

    map的用法 ——.我们来分析map在python的源码 class map(object): """ map(func, *iterables) --> map ...

  9. C语言Ⅰ博客作业05

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9827 我在这个课程的目 ...

  10. 【Linux 网络编程】常用套接字类型

    常用套接字类型<1>流式套接字(SOCK_STREAM)---TCP      提供面向连接的.可靠的传输服务,数据无差错,无重复的发送,      且按发送顺序接收.<2>数 ...