lazysheep 10 X 10
Last updated: 2017-05-12
lazysheep:~ Desktop$ node 聊一聊像素px.js

> Post.tags
css

> Post.prev
node菜鸟笔记(2)---node 的模块实现

> Post.next
node菜鸟笔记(1)---Mongodb+express实现简单登陆注册
聊一聊像素px

今天看bootstrap响应式布局时时遇到了十分常见但是又不理解的<meta name="viewport" content="width=device-width, initial-scale=1">然后仔细在网上查了资料后 在这里整理整理

思考

  1. iphone6s 的分辨率是1920px * 1080px
  2. iphone6s 全屏截图文件的尺寸是1242px * 2208px
  3. iphone6s 的宽度是414px
  4. iphone6s 不加 viewport 的情况下,window.innerWidth = 980px
  5. iphone6s 加 viewport 且 scale 都为1的情况下,window.innerWidth = 414px(及iphone6s的宽度)
  6. iphone6s 加 viewport 且 scale 都为.5的情况下,window.innerWidth = 829px

    这些 px 单位都是啥?

什么是像素

  • 像素是度量的单位,可以理解为点。点组成线,线组成面,一个页面也就是有n多个像素点组成。

什么是设备像素

  • 设备的物理像素,其尺寸大小是绝对的。

什么是分辨率

  • 分辨率是屏幕图像的精密度,是指显示器所能显示的像素的多少。屏长的设备像素 × 屏宽的设备像素。
  • iphone6s 的分辨率是1920px * 1080px 即横向能显示1080个像素点,纵向能显示1920个像素点。

来测试一下

iphone5的分辨率是1136像素×640像素,即横向能显示640个像素点,纵向显示1136个像素点。横向能显示640px,那如果我的页面上的div设置为320px的宽的话,那手机上应该显示的是该div只占一半的宽度,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style media="screen">
* {
margin: 0;
padding: 0;
}
.test {
width: 320px;
height: 640px;
background-color: #009688;
}
</style>
</head>
<body>
<div class="test">

</div>
</body>
</html>

project
然而我们发现只占了屏幕的三分之一OMG!难道出BUG了吗 QAQ
不不不!!!
这是因为iphone默认的viewport宽度是980px也就是说iphone的默认html的页面大小为980px铺满屏幕
但是当我们添加了<meta name="viewport" content="width=device-width, initial-scale=1">
惊奇的发现
project
竟然铺满屏幕了!!!!是不是又出现BUG了!!!其实早有预谋
<meta name="viewport" content="width=device-width, initial-scale=1">这里的这个标签的意思是 将 viewport 宽度设为设备宽度,初始的缩放比例为一倍,那么这里的设备宽度到底是什么呢?请看下面

什么是逻辑像素

  • CSS 的像素单位,其尺寸大小是相对的,也称为独立像素。(及手机的设备宽度)。
  • 只要两个屏幕逻辑像素相同,它们的显示效果就是相同的。但是它们显示的精确度及清晰度却不同。因为它们的设备像素不一定相同。

    举个例子

iphone3gs,逻辑分辨率是480px 320px,物理分辨率也是480px 320px。
iphone4,逻辑分辨率和3gs一样是480px 320px,但是物理分辨率变成了960px 640px。采用Retina视网膜屏幕。

project
假设有个邮件列表界面,我们不妨按照PC端网页设计的思维来想象。3gs上大概只能显示4-5行,4s就能显示9-10行,而且每行会变得特别宽。但两款手机其实是一样大的。(因为iphone4的物理分辨率是3gs的两倍)如果照这种方式显示,3gs上刚刚好的效果,在4s上就会小到根本看不清字。
project
在现实中,这两者效果却是一样的。这是因为Retina屏幕把2x2个像素当1个像素使用。比如原本44像素高的顶部导航栏,在Retina屏上用了88个像素的高度来显示。导致界面元素都变成2倍大小,反而和3gs效果一样了。画质却更清晰。

所以只要两个屏幕逻辑像素相同,它们的显示效果就是相同的。但是它们显示的精确度及清晰度却不同。因为它们的设备像素不一定相同。

dpi(dots per inch)

  • 像素密度,表示水平或垂直方向每英寸长度的像素数目

ppi(pixels per inch)

  • 像素密度,表示沿对角线每英寸长度的像素数目

缩放因子(Scale Factor)

  • 逻辑像素相对于设备像素的放大比例,可通过 window.devicePixelRatio 获得,但二者并不完全等同。

关系一:

  设备尺寸 × 像素密度 = 分辨率(设备像素)

  举例:

  iphone6s 对角线长度为5.5 inches,像素密度401 ppi,分辨率 1920 * 1080,计算可得对角线的设备像素为2205.5。

  5.5 * 401 = 2205.5

关系二:

  逻辑像素 = 设备像素 × 缩放因子

  举例:

  iphone6逻辑像素为667 375,分辨率为1334 750,缩放因子为2

  1个逻辑像素 = 设备宽度的1/375

  1个设备像素 = 设备宽度的1/750

  1/375 = 1/750 * 2

常见的设备的分辨率

project

iphone6 plus

iphone6s的 ppi 达到了401,按照比率,它的缩放因子应该等于2.6。
project
但是2.6这一奇葩的比例不太方便切图,所以 iphone6s 就直接改成了3,然后再整体压缩87%(2.6 / 3)。这也是为啥iphone6s 全屏截图的尺寸是1242 * 2208。

dpr 适配

devicePixelRatio 适配要解决的问题是:在设置了 viewport,width=device-width 的情况下,如何画出1px(设备像素)的问题。
dpr=2意味着 CSS 中的1px 会用两个设备像素来渲染,在 iphone6s 上更会用3个设备像素来渲染。
手机淘宝的做法是使用 js 动态设置 viewport 的 initial-scale。

1
2
3
4
5
6
7
8
9
10
11
12
//参考代码
var metaEl = doc.createElement('meta');
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ',minimum-scale=' + scale + ',user-scalabl=no');
if (docEL.firstElementChild) {
document.documentElement.firstElementChild.appendChild(metaEL);
} else {
var warp = doc.createElement('div');
warp.appendChild(metaEL);
doccument.write(wrap.innerHTML);
}

参考

1px究竟是多大