移动端适配 后篇(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 以父元素 ...
随机推荐
- [VBA]合并工作簿优化版
Sub 合并工作簿数据()Dim arrDim i As Integer, j As Integer, x As IntegerDim f As String, m As String, n As S ...
- React 之form表单、select、textarea、checkbox使用
1.案例如下 import React from 'react'; /** * 非约束性组(类似defaultValue等属性,不可以程序修改): <input type="text& ...
- 使用apicloud开发移动端APP,IOS list页面滚动卡顿解决记录
给内容容器添加样式:-webkit-overflow-scrolling:touch; -webkit-overflow-scrolling:属性控制元素在移动设备上是否使用滚动回弹效果. auto: ...
- unieap 建库
create tablespace unieap datafile 'unieap.dbf' size 100M reuse autoextend on next 50M;1. 2.drop user ...
- [译]深入 NGINX: 为性能和扩展所做之设计
来自:http://ifeve.com/inside-nginx-how-we-designed-for-performance-scale/ 这篇文章写了nginx的设计,写的很仔细全面, 同时里面 ...
- 【Deep Learning Nanodegree Foundation笔记】第 9 课:Model Evaluation and Validation
In this lesson, you'll learn some of the basics of training models. You'll learn the power of testin ...
- 【Deep Learning Nanodegree Foundation笔记】第 1 课:INTRODUCTION Welcome
Welcome to the Deep Learning Nanodegree Foundations Program! In this lesson, you'll meet your instru ...
- OpenTSDB查询和写入毫秒级数据
由于OpenTSDB没有支持Java的SDK进行调用,所以基于Java开发OpenTSDB的调用将要依靠HTTP请求的方式进行. 1.毫秒级数据写入 /api/put:通过POST方式插入JSON格式 ...
- Johnson算法学习笔记
\(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...
- P1115 最大子段和(简单DP)
题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入格式 第一行是一个正整数NN,表示了序列的长度. 第二行包含NN个绝对值不大于1000010000的整数A_iAi,描述了这段序 ...