动态rem解决移动前端适配
背景
移动前端适配一直困扰很多人,我自己也是从最初的媒体查询,到后来的百分比,再到padding-top这种奇巧淫技,再到css3新单位vw这种过渡转变 但这些都或多或少会有些问题,直到使用了动态rem 才真正不再在适配这个问题上发愁 只因为叫动态rem 是因为他是真正意义上随着屏幕的大小来变化的。
rem
rem官方解释是 font size of the root element 字面意思就是 根元素的font-size值 也就是rem是相对于元素的
如下代码
<html>
<meta charset="utf-8"/>
<head>
<style>
html{ font-size:10px;}
.p1{font-size:1rem;}
.p2{ font-size:2rem;}
</style>
</head>
<body>
<p class="p1">这是一个1rem字体</p>
<p class="p2">这是一个2rem的字体</p>
</doby>
</html>

从最终效果可以看出文档中元素的字体大小是基于html根元素的 p1的font-size为10px p2的font-size是20px
viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
在移动开发时我们都会有上面这段代码
- viewport :虚拟窗口大小
- width: 控制viewport大小 可以自己设定值如320px(很少用) 一般设置为device-width(设备宽度)
- initial-scale 初始缩放比例 即页面初次加载时的缩放比例默认为1
- maximum-scale:用户可缩放到的最大比例
dpr(device pixel ratio)
设备像素比dpr
要了解这一概念还得清楚另外两个概念
设备物理像素
通俗的讲设备屏幕有多少个可以闪烁的点 是一个具体的概念 比如iphone6横向就有750个可以改变颜色的点 类似与电视机 如果家里有10年前买的大头电视,你趴在屏幕前仔细看能看到一个个RGB的点 这就是设备的物理像素
设备独立像素
设备独立像素是一个虚拟的概念,如程序中的css 比如我们将一个div宽度设置为10像素 那么在pc上系统会将这个div显示在屏幕的10个点上
dpr = 设备物理像素/设备独立像素
程序中的1px占据设备上的几个最小物理点可以这么理解
iphone3G 设备物理像素320个点 设备独立像素320px 那么dpr就是1
iphone6 设备物理像素750个点 设备独立像素375px 那么dpr就是2
也就是我们css中写的1px其实不等于设备实际上的那1px 也可能等于设备上的2px
根据dpr我们就可以灵活的在移动端缩放页面比例
可以通过window.devicePixelRatio来获取dpr


动态rem
通过上面的rem,viewport,以及dpr我们就可以完成我们的终极适配了,告别死板写法 不再这样写死 我们知道了设备的dpr就可以明确的知道缩放多少,而且这样还解决了很难解决的1px横线的问题
我们需要这样一段js代码
(function (doc, win) {
console.log("dpr:"+win.devicePixelRatio);
var docEle = doc.documentElement,
isIos = navigator.userAgent.match(/iphone|ipod|ipad/gi),
dpr=Math.min(win.devicePixelRatio, 3);
scale = 1 / dpr,
resizeEvent = 'orientationchange' in window ? 'orientationchange' : 'resize';
docEle.dataset.dpr = dpr;
var metaEle = doc.createElement('meta');
metaEle.name = 'viewport';
metaEle.content = 'initial-scale=' + scale + ',maximum-scale=' + scale;
docEle.firstElementChild.appendChild(metaEle);
var recalCulate = function () {
var width = docEle.clientWidth;
if (width / dpr > 640) {
width = 640 * dpr;
}
docEle.style.fontSize = 20 * (width / 750) + 'px';
};
recalCulate()
if (!doc.addEventListener) return;
win.addEventListener(resizeEvent, recalCulate, false);
})(document, window);
- 获取设备dpr
- 算出缩放比例 scale = 1/dpr
- 创建meta以及属性
- 将scale值赋给initial-scale,maximum-scale
- meta插入到文档中
- 创建屏幕大小改变重新计算函数并监听
最终效果

使用sass同步psd
当我们拿到psd的时候可能要把psd的图尺寸转换为rem,之前一个同事有一个很好的方法可以完全按照psd的的尺寸来书写,但要用到sass,使用sass可以大大提高开发效率,下面是sass的一个mixin方法将rem和px做了转换
如下hotcss.scss
@function px2rem( $px ){
@return $px*750/$designWidth/20 + rem; //这句是不是感觉很熟悉 这句其实跟上面的那段js是对应的
}
$designWidth : 750; //如设计图是750
在我们的style.scss中
@import 'px2rem.scss';
$designWidth : 750; //如设计图是750
.banner{width:px2rem(300)}//如设计稿上的banner是300px 就免去计算环节
参考文档
https://segmentfault.com/a/1190000003690140
https://github.com/imochen/hotcss
http://div.io/topic/1092
http://www.w3cplus.com/css/A-pixel-is-not-a-pixel-is-not-a-pixel.html
动态rem解决移动前端适配的更多相关文章
- 本周汇总 动态rem适配移动端/块状元素居中/透明度
1.动态rem适配移动端 !function(){ var width = document.documentElement.clientWidth; var head=document.getEle ...
- 了解真实的『REM』手机屏幕适配
rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...
- Web移动端页面 --响应式和动态REM
响应式 什么是响应式页面呢? 顾名思义响应式页面就是能做出响应的页面,它的页面效果不是定死的,会随着用户的改变而改变. 如何着手响应式有以下几个思考的方向 找一份设计图 使用Media Query 隐 ...
- 真实的『REM』手机屏幕适配
rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...
- 动态rem与1px边框问题的理解
当我们在项目开发中,拿到设计师的设计图,满怀欣喜的准备按照设计图将页面实现出来的时候,我们通常会遇到这个问题: 如何将页面的内容按照在不同手机屏幕浏览的情况下,比例都是不变的呢?这个时候我们就需要使用 ...
- Rem实现移动端适配
移动端适配 web页面跑在手机端(h5页面) 跨平台 基于webview() 基于webkit 常见适配方法 pc端采用display:inline-block,让div盒子横着排 移动web:采用定 ...
- 九、响应式发:rem和less(适配移动端)
一.响应式开发 响应式开发优先适配移动端又兼容到pc端 官网:https://less.bootcss.com/usage/ 教程:https://www.w3cschool.cn/less/ rem ...
- JavaWeb之动态代理解决request请求编码问题
动态代理解决编码问题 1.设计模式 出现原因:软件开发过程中,遇到相似问题,将问题的解决方法抽取模型(套路) 常见设计模式:单例,工厂,适配器,装饰者,动态代理. 2.装饰者模式简单介绍 谷歌汽车开发 ...
- 解决React前端在开发环境的跨域问题
在前后端分离的分布式架构中,跨域是一道无法绕过去的门槛,众所周知,生产环境上解决跨域最便捷的方式是使用Nginx来处理,那么,在本地开发环境又该如何处理呢? React框架里处理跨域问题,可以使用ht ...
随机推荐
- 自己从0开始学习Unity的笔记 IV (C#循环练习-数字猜谜游戏)
想起来现在基础的已经学了不少了,那么这次试一下用while写一个数字猜谜的. Random roll = new Random(); //建立一个骰子 , ); //让骰子在1-100内随机一个数 ; ...
- 瞄一眼,带你走进SparkSQL的世界
本文由 网易云发布. 作者:范欣欣(本篇文章仅限知乎内部分享,如需转载,请取得作者同意授权.) 最近想来,大数据相关技术与传统型数据库技术很多都是相互融合.互相借鉴的.传统型数据库强势在于其久经考验 ...
- 【12c OCP】CUUG OCP认证071考试原题解析(33)
33.choose the best answer View the Exhibit and examine the structure of the ORDER_ITEMS table. Exami ...
- Django2.0 URL配置详解
转自:https://www.cnblogs.com/feixuelove1009/p/8399338.html Django2.0发布后,很多人都拥抱变化,加入了2的行列. 但是和1.11相比,2. ...
- shell实战之case语句的选择提示
知识点包括:case语句,cat多行输入,break和exit的区别,wget断点续传,while中断条件写法,函数的使用方法 #!/bin/bash echo "\n1. 本机容器情况如下 ...
- C#-一维数组——★★冒泡排序★★
////★★★★★冒泡排序 ; i < a - ; i++) { ; j < a; j++) { if (age[i] < age[j]) { int zhong = age[i]; ...
- Oracle数据库学习(四):学习中的遇到的问题
一.xhost图形化界面安装问题 问题1:运行xhost +命令,出现命令没有找到错误 原因:Linux系统没有安装xhost图形化包. 解决办法:安装xhost图形化包,命令如下: yum what ...
- 汉诺塔的python 动画演示
1.简介 古代有一座汉诺塔,塔内有3个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示.有一个和尚想把这n个盘子从A座移到C座,但每次只能移动一个盘子,并且自移动过程中,3个 ...
- PS2模拟器 PCSX2 新手向
1.模拟器的下载 1.1百度网盘地址:http://pan.baidu.com/s/1i3kt7bJ (已经整合了PS2BIOS的模拟器下载,比较新的版本,适合新手) 1.2高端玩家可以下载: 官网g ...
- destoon调用方法汇总 ---转载
根目录.模板目录和样式目录:{DT_PATH}{DT_SKIN}导入头脚:{template 'header'}{template 'footer'}对应模块首页:{$MODULE[$moduleid ...