首先需要说明一点,css像素不等同于物理像素,css像素是一个抽象单位,而物理像素是实实在在,大小固定的像素点。
一、做移动端需要了解的四个像素
物理像素
物理像素的实际大小及个数由设备本身决定。设备独立像素
设备独立像素也是根据设备而定,生产出来就固定不变,iPhone6的设备独立像素是375 X 667。当你打开浏览器开发者模式,调成移动端就可以看到,它是css像素转换成最终物理像素的一个重要媒介。CSS像素
css像素浏览器上的概念,在没有做适配之前,它和实际物理尺寸扯不上半毛钱关系,css像素大小是随用户放大或缩小而改变的。最终转换成物理像素到设备上成像。位图像素
图片尺寸相关的像素单位,如果一个位图像素刚好放在一个物理像素上成像,那么这时的显示效果最好,如果一个位图像素交给多个物理像素来显示则会失真(放大),如果一个物理像素要塞下多个位图像素,则会锐化。
二、像素比
概念:在一个方向上(如X轴上)占满一块屏幕所需要的物理像素个数 / 所需要的设备独立像素个数
好,那么来算一下iPhone6的像素比 :iPhone6的X轴上的物理像素个数为750 ,而iPhone6的X轴上的设备独立像素为375 ,所以像素比为750 / 375 = 2如果按面积来比就不是2了
三、视口
移动端是如何将PC端的站点放到屏幕里面显示而不产生横向滚动条的呢?
布局视口
布局视口的尺寸各浏览器厂商提供了一个默认值,它决定页面元素要不要换行,移动端缩放操作不影响布局视口,而PC端缩放会影响布局视口。
一般PC端页面960 css像素视觉视口
视觉视口的实际面积其实就是屏幕大小,但是它的尺寸是会改变的,因为他的单位是CSS像素,当你放大页面,你屏幕上的CSS像素点面积逐渐变大,屏幕所能呈现的CSS像素个数逐渐变少,所以视觉视口的尺寸逐渐变小,不要觉得这是谬论,你可以调用API取出视觉视口大小,当你一边放大页面,这个值一边变小。默认移动端的视觉视口是980CSS像素,这就意味着你移动端屏幕可以看到整张网页,视觉视口的作用就是为了要包住整张网页。- 将布局视口的大小设置为设备独立像素的尺寸
<meta name="viewport" content="width = device-width"/>
四、缩放
- 用户缩放
用户缩放改变的是视觉视口,不会改变布局视口 - 系统缩放
系统缩放是指设置initial-scale=xx来进行缩放,系统缩放会改变布局视口和视觉视口
五、获取各视口宽度
- 布局视口
let width = document.documentElement.clientWidth
- 视觉视口
let width = window.innerWidth
六、设置完美视口
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,maximum-scale=1">
- width=device-width 将布局视口尺寸设置为设备独立像素尺寸。
- initial-scale=1 将缩放比设为1,并将布局视口和视觉视口尺寸设置为设备独立像素尺寸。
- maximum-scale=1 maximum-scale=1 IOS不支持initial-scale,所以要设置最大缩放和最小缩放。
- user-scalable=0 禁止用户缩放
七、适配
设置完完美视口就会产生一个问题:在不同设备上元素的高宽比不一样,因为不同的设备布局视口大小不一样,iPhone6为375 css单位 ,而iPhone6plus为414css单位,而你的代码写10px时,所占据的屏幕比例是不一样的,所以就需要我们做适配工作。
rem适配方案
rem适配的前提是已经设置了完美视口,已经将布局视口的宽度设置成了设备独立像素的宽度。然后将跟标签的font-size大小设置为布局视口的大小,或者布局视口的百分之多少,如布局视口的1 / 16 ,那么 16rem 就占据整个屏幕宽度,8rem就占据宽度的一半,所有设备上都一样。- 一份最粗糙的rem适配代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1,maximum-scale=1,user-scalable=0,maximum-scale=1">
<title>菜鸟教程(runoob.com)</title>
<style>
* {
margin: 0;
padding: 0;
}
.re {
width: 180px;
height: 8em;
background: #000;
}
</style>
</head>
<body>
<div class="re"></div>
</body>
<script>
// 将跟标签的字体大小设置为布局视口宽度
var rSize = document.documentElement.clientWidth;
console.log(rSize);
// 获取跟标签
var html = document.querySelector('html');
html.style.fontSize = rSize/16+'px';
// 以上代码会有一个问题:根标签的font-size有可能会被改变
// 所以要加上!important
let style = document.createElement("style")
let rSize = document.documentElement.clientWidth/16
// 16分之1的布局视口大小
style.innerHTML = "html{ font-size: "+ rSize + "px!important }"
document.head.appendChild(style)
</script>
</html>
viewport适配方案
viewport适配方案的思路是将布局视口的宽度设置为设计图的宽度,但是安卓手机是不允许直接设置布局视口宽度,所以就需要通过设置 initial-scale值来改变布局视口大小,这个值的大小为:设备独立像素 / 设计图位图像素- 一份viewport适配方案代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- 先将设备独立像素大小赋值给布局视口值,之后替换掉 -->
<!-- 因为js暂时没法直接读取设备独立像素 -->
<meta name="viewport" content="width=device-width>
<title>菜鸟教程(runoob.com)</title>
<style>
* {
margin: 0;
padding: 0;
}
.re {
width: 180px;
height: 8em;
background: #000;
}
</style>
</head>
<body>
<div class="re"></div>
</body>
<script>
var target = 375;
var scale = document.documentElement.clientWidth/target;
console.log(scale)
var meta = document.querySelector("meta[name='viewport']")
meta.content = "initial-scale="+scale+",maximum-scale="+scale+",user-scalable=0,maximum-scale="+scale
</script>
</html>