设备像素比(dpr)= 物理像素(手机渲染像素、分辨率)/设备独立像素(手机所显示元素的大小)
视口(viewport)
布局视口(获取浏览器布局视口高度,包括内边距,但不包括垂直滚动条、边框和外边距。):
document.documentElement.clientWidth / clientHeight
视觉视口(获取浏览器视觉视口高度(包括垂直滚动条)):
window.innerWidth / innerHeight
理想视口(屏幕大小,设备的分辨率/设备像素比):
screen.width / height
当页面缩放比例为100%
时,CSS像素 = 设备独立像素
,理想视口 = 视觉视口
。
Meta viewport
借助<meta>元素的viewport来设置视口、缩放。
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
1px问题
在设备像素比 > 1的设备上,渲染 1px 实际上被多个物理像素填充,所以对于有些屏幕看起来1px比实际粗
@svg border_1px { height: 2px; @rect { fill: var(--color, black); width: 100%; height: 50%; } } .example { border: 1px solid transparent; border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch; }
rem 适配
rem
是相对于html
节点的font-size
来做计算的,将font-size设为布局视口的1/10,相当于1rem = 1/10 * 布局视口宽度
//自适应设备 (function (doc, win) { var docEl = doc.documentElement, isIOS = navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), dpr = isIOS ? Math.min(win.devicePixelRatio, 3) : 1, dpr = window.top === window.self ? dpr : 1, //被iframe引用时,禁止缩放 resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'; docEl.dataset.dpr = dpr; var recalc = function () { var width = docEl.clientWidth; if (width / dpr > 750) { width = 750 * dpr; } docEl.dataset.percent = 100; docEl.style.fontSize = width / 10 + 'px'; }; recalc(); if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); })(document, window);
viewport 适配(大部分浏览器已经兼容,原理类似rem)
1vw = 1% window.innerWidth;1vh = 1% window.innerHeight
参考资料:https://juejin.im/post/5cddf289f265da038f77696c