涉及到的一些名词, 详细解释可参考 移动端适配前篇--移动端适配 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. WPF Prism Request Navigate activation error

    其他测试项目时没有问题,但是有些项目有时候导航一直报错误! Referring the StockTraderRI, I created a popup region in my shell infB ...

  2. jQuery.validator.addMethod自定义验证

    jQuery.validator.addMethod("numOrLetter", function(value, element) { return this.optional( ...

  3. Amphorae 与 Octavia Worker 的安全通信实现

    前言 在前面的章节中我们记录了 LoadBalancer.Listener.Pool.Member 等等 Octavia 核心资源对象的创建流程,本篇我们在此之上继续讨论处于 LB Managemen ...

  4. python 生成excel,并下载到本地

    from django.shortcuts import reverse,redirect,render from operations import models import xlwt impor ...

  5. mac book 显示隐藏系统文件夹

    打开Finder Finder->Finder Preferences->勾选 Device分类下的MAC username 在Teminal下输入命令 defaults write co ...

  6. 利用Ansible模块copy和fetch进行主机间文件的传递

    场景: java应用程序和Ansible不在同一台机子,要读取的文件又在另一台主机. 主机a不能保存文件,可以临时保存. 文件都在主机b上保存. 需求: 需要将文件从主机c传到主机b,再从主机b传到主 ...

  7. TP5报错Fatal error: require(): Failed opening required '/home/www/xx/public/../thinkphp/start.php

    https://jingyan.baidu.com/article/afd8f4deb784fe34e386e97b.html https://www.cnblogs.com/300js/p/9224 ...

  8. 【字符串大模拟】潜伏者—— NOIP2009原题

    洛谷连接 就一道黄题没啥可以说的……就是要细心…… 学到了神奇的优化 ios::sync_with_stdio(false); cin优化,能跑的比scanf快!棒!(不过要开std) 这题真的还挺简 ...

  9. 【7.9校内test】T1挖地雷

    (土气的名字万里挑一丫丫) 然后这个题是个递推,lz的考场想法: 3个的最好确定,先把3个的确定下来,然后从这个点往前推,从这个点往后推这么算吧qwq 然后码长:也是很nice,最关键的是,我都写的这 ...

  10. python3 enum模块的应用

    python枚举模块的学习 ps:小编刚开始学习没多久,部分资源来源于其他网友,如有出错,麻烦联系修改哈,互帮互助,共同进步 一.枚举与字典类型 字典类型的缺点:1.值可变 2.没有防止相同标签的功能 ...