移动端适配 后篇(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 汇总多个工作簿() Application.ScreenUpdating = False Dim wb As Workbook, f As String, l As String, n As ...
- Python Module_sys/random
目录 目录 前言 软件环境 Python标准库初识 Python常用的标准库模块 dir 函数使用方法 sys操作系统功能模块 sysstdinsysstdoutsysstderr标准IOError流 ...
- Python 解决八皇后问题
问题介绍 八皇后问题是一个以国际象棋为背景的问题:如何能够在 \(8\times8\) 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一 ...
- django 生成后台管理
在应用下的admin.py中注册模型类.告诉djang框架根据注册的模型类来生成对应表管理页面. 1) 注册管理数据表 from django.contrib import admin from us ...
- unieap platform eclipse.ini vm设置
-vm C:\Program Files (x86)\Java\jdk1..0_45\bin\javaw.exe -startup plugins/org.eclipse.equinox.launch ...
- Spring-QUARTZ定时任务demo
Quartz定时任务demo下载: https://github.com/AliceSunCong/quartz 大致流程: **1.pom文件引入QUARTZ依赖** <dependency& ...
- IOS CocoaPods详细使用方法
自从有了CocoaPods以后,这些繁杂的工作就不再需要我们亲力亲为了,只需要我们做好少量的配置工作,CocoaPods会为我们做好一切 一.什么是CocoaPods 1.为什么需要CocoaPo ...
- 使用 Blender* 重新拓扑 VR 和游戏素材
本文介绍如何将网格重新拓扑成一个整洁的低密度模型,然后 UV 解包该网格,以便将纹理贴添加至新模型.本文还将探讨如何使用免费工具,比如 Blender* 及其 Bsurface 插件,重新拓扑雕塑的 ...
- java带图形界面的五子棋
Main: package BlackWhite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowL ...
- 【转】【mysql面试】https://blog.csdn.net/hanfazy/article/details/14520437
公司招聘MySQL DBA,也面试了10个2年MySQL DBA工作经验的朋友,谈谈自己的心得,欢迎大家指点. 1 2年MySQL DBA经验 其中许多有水分,一看到简历自我介绍,说公司项目的时 ...