CSS像素、物理像素、逻辑像素、设备像素比、PPI、Viewport
关于移动端适配,你必须要知道的
这篇主要介绍适配的相关知识点,不变的那种
至于经验类:
细看动画排坑技巧(1px问题、适配iPhonex问题、图片模糊问题
实践类:媒体查询、屏幕适应(百分比布局、缩放布局、rem自适应
设备像素/像素密度/设备像素比
指尖上行
**
设备像素
像素密度ppi
判断retina屏幕可以通过ppi判断,但更方便的是通过dpr判断
设备像素比dpr
js:
Window.devicePixelRatio 获取当前设备的dpr
css:
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){
}
关于市面上各个手机的 ppi、dpr等可以在 http://screensiz.es/ 这里查看
一般来说,物理像素=设备独立像素(dp)设备像素比
设备独立像素可以在开发者工具看到
但是也有例外:
iPhone 6、7、8 Plus 实际物理像素 = 1080 x 1920,设备独立像素=414 x 736
,设备像素比为3
设备独立像素 设备像素比 = 1242 x 2208
实际上,手机会自动把1242 x 2208
个像素点塞进1080 * 1920
个物理像素点来渲染,我们不用关心这个过程,而1242 x 2208
被称为屏幕的设计像素
。我们开发过程中也是以这个设计像素
为准。
**在iOS
、Android
和React Native
开发中样式单位其实都使用的是设备独立像素。
在写CSS
时,我们用到最多的单位是px
,即CSS像素
,当页面缩放比例为100%
时,一个CSS像素
等于一个设备独立像素。
为了适配所有机型,我们在写样式时需要把物理像素转换为设备独立像素:例如:如果给定一个元素的高度为200px
(这里的px
指物理像素,非CSS
像素),iphone6
的设备像素比为2
,我们给定的height
应为200px/2=100dp
。
viewport
深入了解viewport和px
指尖上行
latout viewport
latout viewport:document.documentElement.clientWidth\document.documentElement.clientHeight
浏览器默认的窗口,在移动端设备为了不让pc页面因为viewport太窄而使页面错乱,一般将vp设置为较宽的,比如980px;在这样的窗口下手机呈现就像在pc上打开页面一样,只是手机是一个小小的框选出小小一部分展示给用户;
手机就像一个放大倍数为1的放大镜;
部分机型默认viewport大小:
那么手机框选的这个框到底有多大呢?
visual viewport:window.innerHeight\window.innerWidth
ideal viewport
这是一个理想的、抽象的视图,在此视图下,图片和文字无论什么设备、分辨率,看起来都会保持差不多的大小;
知道ideal port,我们的目标是将latout viewport设置成ideal viewport的宽度,此时如果页面缩放比例同时满足100%,那么此时 CSS像素 = 设备独立像素,理想视口 = 视觉视口
===》
让当前layout view 宽度=设备的ideal viewport宽度,同时不允许用户手动缩放
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=0"
>
device-width 即设备独立像素宽度
initial-scale=1.0 缩放是以ideal viewport作为参考,当设置initial-scale=1.0即缩放100%,言外之意也就是使得layout viewport=ideal viewport
当然 viewport也可以通过js动态修改
== 使用document.write ==
document.write('<meta name="viewport" content="width=变化值">');
== 使用setAttribute ==
<meta id = "test" name="viewport" content="width=device-width">
var vp = document.getElementById('test');
vp.setAttribute('content','width=变化值')
我们直观地理解一下viewport的重要性:
刚开始接触移动页面重构,是不是很迷惑应该按照多大的尺寸制作?320、640还是720?按照640的设计稿重构完页面,是不是还需要写其他尺寸来适配不同的屏幕大小?——这源于对viewport和px的不了解。
已经重构了好多移动页面,但是对为什么要按照640的大小来设计页面,不清楚答案。给元素赋予固定的像素值,但是奇怪的是在不同的手机里看起来都差不多大小,不需要另外去适配,真是太爽了。为什么?不知道耶。——这源于对viewport和px的不了解。
一个栗子:
机型iPhone4s | 已知 |
---|---|
手机分辨率:960*640 ppi:326 viewport默认:980px ideal viewport/device-width:320px |
iPhone4S如果不设置viewport,他就会默认是980px,就像把屏幕分成980份(不是屏幕分辨率的640px哦!)。
此时如果设置一个元素为100px*100px,看起来就是屏幕的100/980
iPhone4S如果设置viewport width=device-width(device-width 即设备独立像素宽度),他就会是320px,就像把屏幕分成320份(不是屏幕分辨率的640px哦!)。如果设置一个元素为100px*100px,看起来就是屏幕的100/320
即同样是设置元素100px,但是在不同的viewport渲染下,元素大小不一样。因为归根结底css里的px不是物理上的绝对长度,而是根据一个占比值。1px等于将屏幕分成无法分割的方格,最小的那个方格边长即为1px;
如果确定最小方格?取决于将屏幕怎么分
当viewport为浏览器默认时(大部分机型为980px)此时不同机型下的1px为屏幕的1/980
当viewport为device-width 设备独立像素宽度时, 此时不同机型下的1px又不同
所以归根结底,我们的适配不是为了在不同的机型上展示一样大小的元素,
而是将元素根据不同大小的屏幕适配成大致相同的比例;
比如一个眼睛,同样是眼睛,长在乐山大佛脸上就有1米长,长在人脸上就几十厘米,但是归根结底不变的是眼睛占脸的比例(不可能整个脸都是眼睛吧~
设置了viewport,width=device-width,以下机型的device宽依次为375px、360px、360px、320px。
咋来的?
iPhone6的屏幕分辨率是1334750px,ppi是326,所以系数是2x。那device-width就等于750/2=375px。 红米1s的屏幕分辨率是1280720px,ppi是312,所以系数是2x。那device-width就等于720/2=360px。
不管哪种尺寸的设计稿,重构都可以用一套方法制作好页面,如果是背景平铺(background-size:100%)、上面的元素px设置大小的话,没问题,能顺利适配其他手机的。如果是固定整体大小重构,再利用js判断屏幕大小进行页面缩放,也没问题,能顺利适配其他手机的。重要的前提是要设置好正确的viewport。
然而我们实际上并不是设置了viewport并配合px就能万事大吉的,事实证明使用设备独立像素只能保证元素在不同手机上显示的效果“类似”,但这并不能保证它们显示完全一致,我们需要一种方案来让设计稿得到更完美的适配。
详情请见页面布局
布局方法论:百分比布局、rem适配布局、缩放布局、flexible方案、vh,vw方案
布局断点:媒体查询、基于内容断点
一般方法论和布局断点配合使用