解决设备像素和 CSS 像素不一样的问题

  • 如果设备像素和 CSS 像素一样, 那么无需处理不会带来任何负面影响。
  • 如果设备像素是 CSS 像素的 2 倍, 那么我们只需将 CSS 像素缩小一半即可。
  • 但是有时候设备像素可能是 CSS 像素的 3 倍 / 4 倍 ...

获取设备像素比DPR(Device Pixel Ratio)

DPR = 设备像素 / CSS 像素:

  • iPhone3GS: 320 / 320 = 1
  • iPhone4S: 640 / 320 = 2
  • iPhone678: 750 / 375 = 2
  • iPhoneX: 1125 / 375 = 3

在 JS 中我们可以通过 ​​window.devicePixelRatio​​ 获取当前的设备像素。

console.log(1.0 / window.devicePixelRatio);// 1 / 1 = 1;1 / 2 = 0.5;

移动端常用适配方案四_移动Web开发+项目实战

如何缩小

通过 ​​<meta name="viewport">​​​ 的 ​​initial-scale​​ 属性来缩小,注意点: 缩放视口后视口大小会发生变化,利用获取像素比动态设置缩放比例改造之前的示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端常用适配方案四</title>
<script>
let scale = 1.0 / window.devicePixelRatio;
let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
document.write(text);
document.documentElement.style.fontSize = window.innerWidth / 7.5 + "px";
</script>
<style type="text/less">
* {
margin: 0;
padding: 0;
}

.top {
position: relative;
}

.top > img {
width: 100%;
height: auto;
}

.top > p {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 80/100rem;
font-size: 36/100rem;
color: #fff;
}

.middle, .bottom {
position: relative;
height: 290/100rem;
}

.main {
border: 1px dashed #0d7efb;
border-radius: 5/100rem;
padding: 10/100rem;
display: inline-block;
position: absolute;
left: 50%;
transform: translateX(-50%);
}

.main > img:nth-of-type(1) {
width: 410/100rem;
height: 270/100rem;
vertical-align: bottom;
}

.main > img:nth-of-type(2) {
width: 84/100rem;
height: 84/100rem;
vertical-align: bottom;
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 60/100rem;
}

.bottom {
margin-top: 35/100rem;
}
</style>
<script src="js/less.js"></script>
</head>
<body>
<div class="top">
<img src="images/bg.png" alt="">
<p>实名认证</p>
</div>

<div class="middle">
<div class="main">
<img src="images/back.png" alt="">
<img src="images/add.png" alt="">
</div>
</div>

<div class="bottom">
<div class="main">
<img src="images/back.png" alt="">
<img src="images/add.png" alt="">
</div>
</div>

</body>
</html>

各种屏幕的显示效果图当然这里就不一一贴图演示了,自行测试。

补充

在上方我们是如何进行缩小的是不是通过将整个视口大小进行缩小的,但是在视口缩小之后我们里面的内容并没有随之而然的进行缩小,这个原因其实也很简单,在如下代码我设置了视口的宽度等于设备的宽度,然后在获取了一下视口的宽度:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>移动端常用适配方案四补充</title>
<script>
console.log(window.innerWidth);
</script>
</head>
<body>
</body>
</html>

然后在 iphone5 上面输出的视口宽度也为 ​​320​​ 没问题:

移动端常用适配方案四_移动Web开发+项目实战_02

然后我在将上面我们进行缩放的代码添加之后再次打印结果如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端常用适配方案四补充</title>
<script>
let scale = 1.0 / window.devicePixelRatio;
console.log(scale);
let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
document.write(text);
document.documentElement.style.fontSize = window.innerWidth / 7.5 + "px";
console.log(window.innerWidth);
</script>
</head>
<body>
</body>
</html>

移动端常用适配方案四_html_03

发现缩小之后并不是 320 而是 640 了,那么这就是为什么我们将整个视口缩小之后它里面的内容并没有进行缩小的原因,原因就是因为它在进行缩小的时候首先会将视口变大一半,原本我设置的宽度等于设备的宽度应该长相如下这么宽:

移动端常用适配方案四_移动Web开发+项目实战_04

但是它发现你要缩小,它会先进行扩大一半,本来如果一样的话两个都是 320 * 480,那么这个时候呢它发现你要缩小它会先进行扩大一半,扩大一半之后就变为了 640 * 960 那么这个时候你就会发现已经与视口的宽度是一个一一对应的关系了,然后在一一对应关系的视口当中先进行布局,布局完毕之后在放入真正视口当中,然后在进行缩小一半,然后正是因为它们是一一对应的关系所以说你看到的界面就没有变小了:

移动端常用适配方案四_移动Web开发+项目实战_05

移动端常用适配方案四_iphone_06