物理像素:dp、比如苹果7主屏分辨率:1334dp*750dp
逻辑像素:px、开发中用到的像素
像素缩放比:dpr、物理像素跟逻辑像素之间的比例关系
像素密度:ppi、屏幕每英寸像素密度【√(1334^2+750^2) / 4.7 = 325.61228......PPI】
逻辑像素不会变,但是物理像素会随着硬件技术提升变化,比如以前1dp的大小约等于1px的大小,现在1dp仅是1px的四分之一(在同样大小的屏幕下,dp变小了,说明主屏分辨率提高了),这时,1px = 2^2dp,目前ppi最高的手机索尼1px约等于8^2dp
像素缩放比DPR在手机出厂的时候就已经定了,js中可以通过window.devicePixelRatio获取到当前设备的dpr;
dpr = dp / px
px = dp / dpr
例外:在苹果6 plus和7 plus的屏幕ppi为401,所以dpr为3,物理像素为1920dp*1080dp
px 按理说应该是 1080/3 = 360,而实际他默认显示为414px,因为苹果6/7plus用了更好的屏幕,但不能让5.5英寸显示内容比6/7的4.7英寸显示内容还少呀,(6/7是375px),所以苹果就采取了措施,选了以下较为折中的a方案:
设计稿都是采用的物理像素,一般750dp较多,屏幕X轴为750dp的设备正常情况下dpr为2,所以750dp的设备在浏览器中显示的最大宽度为750/2 = 375px,当你在body中给一个width为375px的div时,此时显示刚好完全100%宽度,换了其他设备可能就有差距了,所以这里我们就要考虑到页面适配了,在不同手机屏幕尺寸上怎样让看上去效果一样?
vw:相对单位,相对于最大视口宽度,最大视口宽度 = 100vw,所以要设置meta标签:<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">,让内容宽度=视口宽度;
由此得出,一个元素宽度的vw = 该元素在设计稿中的宽度 / (设计稿总宽度/100);
rem:相对单位,1rem = html的font-size,会随着html的font-size改变而改变,html默认font-size是16px,可以将body的font-size还原为16px;
默认html的font-size为16px时rem值对照:
| px | rem |
------------------------
| 12 | 12/16 = .75 |
| 14 | 14/16 = .875 |
| 16 | 16/16 = 1 |
| 18 | 18/16 = 1.125 |
| 20 | 20/16 = 1.25 |
| 24 | 24/16 = 1.5 |
| 30 | 30/16 = 1.875 |
| 36 | 36/16 = 2.25 |
| 42 | 42/16 = 2.625 |
| 48 | 48/16 = 3 |
例:为了方便计算,假设html的font-size设置为100px,设计稿是750dp(iphone6/7):
视窗宽度rem = 375px / 100px = 3.75rem,
那么当用户在不同设备屏幕上访问这个页面呢,例如iphone6/7 plus,会有空白出现,所以要实现适配的话就需要用js代码来动态更改html的font-size了,原理就是获取当前用户设备屏幕宽度,因为rem的值是不变的,我们只需要动态来计算html的font-size就行了:
(function (doc, win) {
var docEl = doc.documentElement,
// orientationchange 事件 用来监听手机屏幕的反转
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;//(window.innerWidth);UC 或者QQ 安卓4.0 以下原生浏览器下面是没有
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 375) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
//DOMContentLoaded dom 加载完成,onload 有什么区别 dom css js OK 才执行的
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
当然现在vw已经兼容除了oprea所有主流浏览器了,可以放心使用,要比rem使用起来简单多了,不管是多大的设计稿,视口宽度都等于100vw,相当于是把最大视口宽度分成了100份;