在不同的屏幕上,CSS像素所呈现的物理尺寸是一致的,而不同的是CSS像素所对应的物理像素具数是不一致的。在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。
物理像素
设备屏幕实际拥有的像素点,屏幕的基本单元,是有实体的。比如iPhone 6的屏幕在宽度方向有750个像素点,高度方向有1334个像素点,所有iPhone 6 总共有750*1334个像素点。
逻辑像素
也叫“设备独立像素”(Device Independent Pixel,DIP),可以理解为反映在CSS/JS程序里面的像素点,也就是说css像素是逻辑像素的一种。
设备像素比(Device Pixel Ratio,DPR)
设备的物理像素与逻辑像素之比。 dpr的全称是window.devicePixelRatio,它等于物理像素 / dips。其实就是一个比例。(物理像素就是一个个的小格子,用来显示不同颜色的。dips可以理解为虚拟像素,就像我们写的css.当dpr=2时,设备像素数为640 x 1136px,而CSS逻辑像素数为320 x 568px。
设备独立像素
不同分辨率的手机,它们在界面上显示元素的大小是多少。一个设备独立像素里可能包含1个或者多个物理像素点,包含的越多则屏幕看起来越清晰。chrome检查元素模拟调试手机设备时显示如375x667
和 320x480
都是设备独立像素。
viewport
视口(viewport)代表当前可见的计算机图形区域。通常与浏览器窗口相同,但不包括浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部分。
布局视窗
布局视口是网页布局的基准窗口,在PC
浏览器上,布局视口就等于当前浏览器的窗口大小(不包括borders
、margins
、滚动条)。在移动端不设置视窗宽度时,页面宽度默认为 980px,页面可以左右滚动。
获取布局视口大小:document.documentElement.clientWidth / clientHeight
视觉视窗
用户通过屏幕真实看到的区域。视觉视口默认等于当前浏览器的窗口大小
(包括滚动条宽度)。
可以简单理解为手持设备物理屏幕的可视区域。也就是你的手机屏幕,所以不同设备的视觉视口可能不同
获取视觉视口大小:window.innerWidth / innerHeight
理想视窗
布局视口宽度 =理想视口宽度 = 视觉视口宽度。要设置content="width=device-width;".
获取理想视窗大小:window.width / height
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
规定了我们的视口宽度为屏幕宽度,不能进行缩放,初始缩放比例为1,就是初始时候我们的视觉视口就是理想视口。
适配方案
rem
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
//如果布局视口大于750就设置750
const clientWidth = docEl.clientWidth > 750 ? 750 : docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth === 750) {
docEl.style.fontSize = '16px';
return
};
//750px的设计稿 1rem = 100px;
//公式:750/clientWidth = 100/fontSize
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'; // 750设计稿
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
设计稿为750px,为了好计算,我们设置1rem = 100px。而750/clientWidth = 100/fontSize,就可以算出fontSize。所以设计稿每个元素的宽高除以100,就是对于的移动端的rem.
postcss-pxtorem
使用一 index.html
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
//如果布局视口大于750就设置750
const clientWidth = docEl.clientWidth > 750 ? 750 : docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth === 750) {
docEl.style.fontSize = '16px';
return
};
//750px的设计稿 1rem = 100px;
//公式:750/clientWidth = 100/fontSize
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'; // 750设计稿
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
postcss.config.js
plugins: {
autoprefixer: {},
'postcss-pxtorem': {
rootValue:100,//根元素的值,即1rem的值
minPixelValue: 2,
propList: ['*'],
}
}
}
使用:设计稿上面的宽度为750px,直接width:750px;设计稿宽度为375px,直接width:375px。
页面渲染为:width:7.5rem
若无配置postcss.config.js,则 设计稿上面的宽度为750px,编写css为width:7.5rem
所以上面的postcss-pxtorem配置的作用就是:将页面中的px/100转化为rem。
设置根元素为百分比
html的font-size默认是16px => 1rem=16px;chrome最小的像素是12px,为了兼容性和好计算,设置1rem = 100px = 16px * 625%。所以我们会看到根元素的font-size设置为625%,设置这个就代表了1rem = 100px。
这样,14px =( 14/100 )rem = 0.14rem。