移动端适配 后篇(rem+vm)
涉及到的一些名词, 详细解释可参考 移动端适配前篇--移动端适配 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)的更多相关文章
- 移动端适配方案(rem+flex)
为什么用rem不用px? 主流:各大网站的移动版绝大多数都是用的rem. 移动端屏幕分辨率差别太大:最低适配的iPhone6,分辨率仅为750*1334.而现在市面上大多数手机,都达到了1080* ...
- 移动端适配方案以及rem和px之间的转换
背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿. 对于移动端开发而言,为了做到页面高清的效果,视觉稿的规范 ...
- pc端与移动端适配解决方案之rem
使用方式: 在html页面开头,引入下面的原生js代码 (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'ori ...
- 移动端适配-rem(新)
概念 对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 移动端像素 设备像素(dp),也叫物理像素.指设备能控制显示的最小物理单 ...
- 移动端适配单位rem
0 写在前面 本周惊喜地发现,其他各个老师的软工班(罗杰老师班和欧阳老师班)的软工项目的alpha版本都已经发布了!(然而我们软工项目还没开始写代码…逃…) 十分好奇的我第一时间下载了一些他们的产品进 ...
- 移动端适配 rem
前置知识: 物理像素(physical pixel,device pixel) 物理像素(设备像素),显示设备中一个最微小的物理部件.每个像素可以根据操作系统设置自己的颜色和亮度. 设备独立像素(de ...
- 浅谈移动端适配-rem
对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 一. 移动端开发有关于像素的概念: 1.设备像素(dp),也叫物理像素.指设备 ...
- 小tips:使用rem+vw实现简单的移动端适配
首先设置meta属性,如下代码: <meta name="viewport" content="width=device-width, initial-scale= ...
- rem移动端适配方案
一. rem vs em 单位 定义 特点 rem font size of the root element 以根元素字体大小为基准 em font size of the element 以父元素 ...
随机推荐
- [mysql]SQL语句-新增/修改 创建时间 更新时间
SQL关键词 要注意大小写 已建表,之前没有创建时间列, 现新增1列创建时间,并设置默认值为当前时间 --添加CreateTime 设置默认时间 CURRENT_TIMESTAMP ALTER T ...
- flutter 网络请求以及数据处理
网络请求使用FutureBuilder来处理 import 'dart:convert'; Widget build(BuildContext context) { return FutureBuil ...
- Linux_基础指令
目录 目录 前言 cd和pwd ls cat du mkdir touch rm cp mv which whereis find ln head和tail wc tar vim useradd 添加 ...
- 阶段3 2.Spring_08.面向切面编程 AOP_4 spring基于XML的AOP-配置步骤
resources下新建bean.xml文件 xmlns:aop 先配置IOC aop 通知类就是logger.id配置为logAdvice表示日志的通知 梳理流程 首先我们在这有个Service它需 ...
- C#, 计算字符串里有多少个指定字符
int number = a.Count<char>(c => c == '@');
- python基础之字符串索引与切片
字符串索引与切片:切片后组成新字符串与原字符串无关系增:str1+str2查:str1[index] str1[start_index:end_index]1,索引从0开始2,根据索引获取元素:索引超 ...
- Dialupass v3.20 汉化绿色版 显示查看拨号上网密码
Dialupass 显示查看拨号上网密码 拨号上网的密码不小心丢了怎么办?这个工具可以帮你!在紧要关头,它会让你体验到它的奇效!有备无患,快收藏这个小东东吧. 这是一款拯救忘记了拨号网络密码的使用者的 ...
- HDU 1176 免费馅饼 (动态规划、另类数塔)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- Go语言中byte类型和rune类型(五)
本篇内容本来准备在上一篇写的,想了想还是拆开写. go语言中字符串需要使用用双引号,而单引号用来表示单个的字符,字符也是组成字符串的元素.go语言的字符有两种: uint8类型,或者叫 byte 型, ...
- [MtOI2019]永夜的报应 题解
题面 题面说的乱糟糟的看起来似乎是个可持久化线性基: 然而~ 一个式子搞定一切: a^b<=a+b 那么把所有数异或起来便是答案: #include <bits/stdc++.h> ...