物理像素
物理像素是屏幕设备的尺寸单位,在不同的设备中1px里可以容纳的像素颗粒是不相同的,所以1px这个单位其实也是有N个像素颗粒填充的。同一尺寸屏幕的每个像素点所能容纳的像素颗粒越多显示效果越清晰,分辨率越高。也即1个像素点所有容纳的颗粒越多,效果越好。现在的手机屏幕用肉眼已经看不到颗粒,这是由于设备支持越来越细小的像素颗粒,这些屏幕被称为retina(视网膜屏幕)。现在假设有一个1px的图片,该图片的1px容纳了1个像素颗粒,现在将该图片放进支持1px可容纳2个颗粒的屏幕中,这会将图片的那个颗粒拆分成两半放进设备的1个px里,而由于该设备的1px必须有两个颗粒才能填满,现在它的两个颗粒都没有被填满,这就会造成图片显示效果模糊。所以不是1px的图片在某个屏幕上显示时非常清楚的,那么它在另一个屏幕上就一定也清楚,清楚不清楚要看屏幕的物理像素。
像素比
像素比指的是1个px单位可以容纳的像素颗粒
分辨率
分辨率=宽*高*像素比。上图中414*736就是屏幕的物理像素、分辨率、尺寸。414*736*3=914112,这个尺寸的屏幕可容纳914112个像素颗粒。pc的像素比是1,所以pc的1920*1080的分辨率则是1920*1080*1=2073600,整个pc屏幕容纳了2073600个像素颗粒。
css像素单位
css中设置尺寸的单位比如100px,指的就是像素颗粒,而不是物理像素。
pc与手持设备的物理像素差别
pc端的像素比是1:1,也就是说如果为某个元素设定一个16px的宽度,那么在屏幕上就有16个像素颗粒。而手持设备的像素比是1:3及其以上,1个px单位必须填充3个px颗粒,那么把pc端的16像素放进手持设备后会发现16个像素颗粒只有5.3个物理像素(16÷3=5.3),单位太小就会导致文字看不清楚。
font-size:16px;
background:#0094ff;
}
为了让手持设备正常显示16px的字号,可以改成48px(16*3)
font-size:48px;
background:#0094ff;
}
viewport布局
viewport是一个视口容器,viewport可以在不改变pc端对元素的尺寸设置就可以立即实现pc端与手机端呈现相同的显示效果。也即viewport可以自动计算从而保证pc端和手持设备的分辨率一致。比如一个pc端的16px的字体,在手机端自动呈现为48px的,不需要手动更改字号大小。
声明viewport
通过content设置viewport的各个配置
width height :指定了视口的宽高为手持设备的宽高
initial-scale:缩放比是2倍(自动将pc端的网页放大两倍,这会导致pc端整体尺寸变大两倍,比如字号16px,将pc端浏览器放大200%就是在手机端呈现的效果)
使用viewport通常都是将自动缩放比设为1,让pc端和手持设备的分辨率保持一致
viewport的问题
viewport的优先自然是不需要我们手动去计算像素比,它包办让pc端和手持设备分辨率看起来一致。但它也有缺点,比如图片在手持设备中会失真。这是由于页面每个元素都计算了像素比,一个16px的文字在手机端被viewport呈现为16*3=48,现在假设一张图片的真实像素是100px,它在pc端正常显示,如果放到手持设备上,那么它会被viewport暴力拉大,100*3=300px,这就会导致图片模糊失真。所以很多程序在手持设备上都把图片做成了字体以避免失真。
rem布局
尺寸单位的对比
px:固定单位,在不同的屏幕下px显示的效果是不一样的,使用em或者rem却可以做到等比缩放
em:根据当前元素的字体大小进行运算得出一个px的值,计算方法是:em*自身的font-size
rem:根据当前文档的根节点<html>节点的字体大小进行运算得出一个px的值,计算方法是:rem*根元素html的font-size
em与rem都有灵活性,适合在移动端布局,两者区别仅在于em看自身的字体大小决定最终尺寸,而rem只看根html元素字体大小决定最终尺寸。浏览器都有默认字体大小,如chrome的默认字体大小是16px,16px=1rem,除非你用css去控制元素的字体大小,否则你页面上的根元素即<html>元素的字体大小就是浏览器的默认字号16px。
rem布局原理
相对于em来说,rem明显更容易计算。使用em来设置元素尺寸,如果当前元素没有设置fontSize,那么你还需要逐层找到当前元素继承的字号大小,而rem只需要知道html节点的字体大小即可。我们主要利用方便计算的rem来实现移动端的布局,这个原理就是通过媒体查询获取当前屏幕的尺寸,然后根据不同的尺寸动态设置html根节点的fontSize,然后rem可以乘以不同屏幕尺寸的fontSize,实现等比例缩放。
html {
font-size: 50px;
}
}
@media screen and (min-width:414px) {
html {
font-size: 64.6875px;
}
}
@media screen and (min-width:640px) {
html {
font-size: 100px;
}
}
div {
font-size:0.48rem; //48px字体。48÷100=0.48
width: 2rem; //200px的盒子 200÷100=2
height:2rem;
background: #ff6a00;
}
<div>鸷鸟</div>
less rem适配
手持设备的尺寸太多,用less进行计算比较方便
/*主流屏幕尺寸列表*/
@screen-size-list: 320px,360px,375px,384px,400px,411px,414px,424px,480px,540px,640px,720px,750px,768px;
/*主流屏幕尺寸列表总长度*/
@secreen-size-list-length: length(@screen-size-list);
/*photoshop设计图尺寸*/
@phtoshop-size: 768px;
/*基字号*/
@base-font-size: 100px;
//主题色
@subject-color: #ff6a00;
//白色
@font-color-white: #fff;
//白色
@font-color-gray: #373737;
//input底色
@input-bg-color: #fa8e65;
/*媒体查询,根据屏幕尺寸设置基font-size*/
.set-screen-font-size(@i) when ( @i =< @secreen-size-list-length ) {
@array-child: extract(@screen-size-list,@i);
@media ( min-width: @array-child ) {
html {
font-size: @array-child / ( @phtoshop-size / @base-font-size );
}
}
.set-screen-font-size( @i + 1 );
}
.set-screen-font-size(1);
dpr rem适配
这个是阿里巴巴的rem布局,算法利用了屏幕的dpr,拷贝以下代码在head元素里,这个方案同样是1rem = 100px,设置元素尺寸的时候直接width÷100得到rem值
以上js代码会自动生成一个viewport,不要再手动设置。具体参考:dpr rem适配
*iphone5的屏幕宽只有320,按照dpr=2计算,它最大只有640的宽度,如果你在css中设置了7rem(700px)的尺寸,那么iphone5的屏幕上就会出现横向滚动条,这种情况逐一要使用width:100%解决。
*高清屏幕dpr = 2用普通图片会模糊,因为四个物理像素要共享一个设备独立像素,会导致模糊效果,请用分辨率是两倍的图片来解决。