新的知识仓库 前端从入门到入土 求关注、star及提建议,不定时更新~
你们都不看的总集篇: 从零开始的大前端筑基之旅(深入浅出,持续更新~)
觉得不错就顺手点个赞吧
在高清屏
下,很多设计稿上的参数就不能像web一样直接拿来用了,不管是H5页面还是RN应用,都需要进行下适配。例如,同样是1px,移动端的1px 就会显得很粗。
那么为什么会产生这个问题呢?主要是跟一个东西有关,DPR(devicePixelRatio) 设备像素比,它是默认缩放为100%的情况下,设备像素和CSS像素的比值。简单地说,这告诉浏览器应该使用多少个屏幕的实际像素来绘制单个 CSS 像素。
还有一个因素也会引起css中px的变化,那就是用户缩放。例如,当用户把页面放大一倍,那么css中1px所代表的物理像素也会增加一倍;反之把页面缩小一倍,css中1px所代表的物理像素也会减少一倍。
在早先的移动设备中,屏幕像素密度都比较低,如iphone3,它的分辨率为320x480,在iphone3上,一个css像素确实是等于一个屏幕物理像素的。后来随着技术的发展,移动设备的屏幕像素密度越来越高,从iphone4开始,苹果公司便推出了所谓的Retina屏,分辨率提高了一倍,变成640x960,但屏幕尺寸却没变化,这就意味着同样大小的屏幕上,像素却多了一倍,这时,一个css像素是等于两个物理像素的。
value = window.devicePixelRatio;
三类viewport
移动设备上的viewport就是设备的屏幕上用来显示我们的网页的那一块区域,但viewport又不局限于浏览器可视区域的大小。ppk把移动设备上的viewport分为layout viewport 、 visual viewport 和 ideal viewport 三类,
为了能在移动设备上正常显示那些传统的为桌面浏览器设计的网站,移动设备上的浏览器都会把自己默认的viewport设为980px或1024px。但带来的后果就是浏览器会出现横向滚动条。我们把这个浏览器默认的viewport叫做 layout viewport,通过 document.documentElement.clientWidth
来获取
桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素,但css中的像素只是一个抽象的单位,在不同的设备或不同的环境中,css中的1px所代表的设备物理像素是不同的。
现在有很多手机分辨率都非常大,比如768x1024,或者1080x1920这样。但css中的1px并不是代表屏幕上的1px,你分辨率越大,css中1px代表的物理像素就会越多,devicePixelRatio的值也越大。因为你分辨率增大了,但屏幕尺寸并没有变大多少,必须让css中的1px代表更多的物理像素,才能让1px的东西在屏幕上的大小与那些低分辨率的设备差不多,不然就会因为太小而看不清。
把代表浏览器可视区域的大小viewport叫做 visual viewport。visual viewport的宽度可以通过window.innerWidth
来获取。
最后有一个能完美适配移动设备的viewport。所谓的完美适配指的是,
- 不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;
- 显示的文字的大小是合适,比如一段14px大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段14px的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。
这个viewport叫做 ideal viewport,也就是第三个viewport——移动设备的理想viewport。
meta标签
移动设备默认的viewport是layout viewport,我们需要的是ideal viewport。这时候轮到meta标签出场了。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
该meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。
meta viewport 有6个属性:
要得到ideal viewport就必须把默认的layout viewport的宽度设为移动设备的屏幕宽度。因为meta viewport中的width能控制layout viewport的宽度,所以我们只需要把width设为width-device这个特殊的值就行了。
<meta name="viewport" content="width=device-width">
在iphone和ipad上,仅设置
content="width=device-width"
,无论是竖屏还是横屏,宽度都是竖屏时ideal viewport的宽度。
<meta name="viewport" content="initial-scale=1">
这句代码也能达到和前一句代码一样的效果,也可以把当前的的viewport变为 ideal viewport。
缩放是相对于 ideal viewport来进行缩放的,当对ideal viewport进行100%的缩放,也就是缩放值为1的时候,就得到了 ideal viewport。因此,默认的 initial-scale 不是1
仅设置
content="
initial-scale=1"
,phone、ipad以及IE 会横竖屏不分,通通以竖屏的ideal viewport宽度为准。推荐两者都写
缩放是相对于ideal viewport来缩放的,缩放值越大,当前viewport的宽度就会越小,反之亦然。例如在iphone中,ideal viewport的宽度是320px,如果我们设置 initial-scale=2 ,此时viewport的宽度会变为只有160px了。
缩放2倍是在实际宽度不变的情况下,1px变得跟原来的2px的长度一样了.所以放大2倍后原来需要320px才能填满的宽度现在只需要160px就做到了
visual viewport宽度 = ideal viewport宽度 / 当前缩放值
因此,禁止用户缩放,并且设置rem的通用的配置如下
/**
* 100 比 1 100px = 1rem
*/
(function () {
const viewport = document.querySelector('meta[name=viewport]');
//下面是根据设备像素设置viewport
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
}
// 设置对应viewport的rem基准值
const docEl = document.documentElement;
const fontsize = 100 * (docEl.clientWidth / 375) + 'px';
docEl.style.fontSize = fontsize;
// 禁止双指放大
docEl.addEventListener('touchstart', function (event) {
if (event.touches.length > 1) {
event.preventDefault();
}
}, false);
// 禁止双击放大
let lastTouchEnd = 0;
docEl.addEventListener('touchend', function (event) {
let now = Date.now();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
}, false);
})();
最后两个函数是防止某些手机浏览器上的强制缩放行为
本文收纳于: 从零开始的大前端筑基之旅(深入浅出,持续更新~)
推荐阅读:
聊聊css position属性及其sticky属性值的特性(吸顶特效)
我之前都不知道还有这个属性值。。。回流(reflow)与重绘(repaint),KFC与MC
每次这两个都会被同时提及,关系就好像KFC边上一定会有MC一样亲密的让人摸不到头脑。viewport和1px | 工具人: 这是1px,设计师: 不,这不是
设计我不行,但吵架我在行啊可食用的「css布局干货」,纯Html示例,可调试 | 水平、垂直、多列
可观看,可调试,可带走,仅此一家,别无分店前端必须掌握的「CSS层叠上下文」讲解 | 纯手工示例,包教包会
妹子与猫,你要哪个?