Open wangning0 opened 7 years ago
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,早操作系统的调度下,每个设备像素都有自己的颜色值和亮度值
设备独立像素(也叫做密度无关像素),可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如:css像素),然后由相关系统转换为物理像素
设备像素比(简称dpi),定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式得到:
设备像素比 = 物理像素/设备独立像素
在JavaScript中,可以通过window.devicePixelRatio 获取当前设备的dpr
在不同的屏幕上,css像素所呈现的大小是一致的,不同的是1个css像素所对应的物理像素个数是不一致的
在普通屏幕下 1个css像素对应1个物理像素 在retina屏素霞,1个css像素对应4个物理像素
一个位图像素是栅格图像(png、jpg、gif等)最小的数据单元,每个位图像素都包含着一些自身的显示信息(显示位置、颜色值、透明度等)
解决方案可以是两倍图片(@2x),然后图片容器缩小50%
缺点是 在普通屏幕下,会造成资源的浪费,图片会失去一些锐利度
最好的解决方案是 不同的dpr下,加载不同的尺寸的图片,通过css媒体查询或者是通过js条件判断都可以
还有一个就是有一个图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸
可以使用hack,将y轴缩小0.5倍
.scale { position: relative; } .scale:after { content: "", position: absolute, bottom: 0px, left:0px; right:0px; border-bottom:1px solid #ddd; -webkit-transform:scaleY(.5); -webkit-transform-origin:0 0; }
或者是设置meta标签,设置viewport(scale 0.5)
<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">
页面被scale 必然会带来一些问题
最好的方案莫过于使用相对单位rem
基于rem的原理:针对不同手机的屏幕尺寸和dpr动态的改变根节点html的font-size大小
rem = document.documentElement.clientWidth * dpr / 10
乘以dpr,是因为页面有可能为了实现1px border页面会缩放(scale)1/dpr,如果没有,dpr=1
除以10,为了取整,方便计算
对于动态改变根节点html的font-size,我们可以通过css做,也可以通过js做
css方式,可以通过设备宽度来媒体查询来改变html的font-size
html{font-size: 32px} // iphone6 @media (min-device-width: 375px) { html{font-size: 64px;} } // iphone6 plus @media (min-device-width: 414px) { html {font-size: 75px} }
这样的做法,没有做到足够的精确,但是够用
javascript方式,通过上面的公式,计算出基准值rem,然后写入样式
var dpr, rem, scale; var docEl = document.documentElement; var fontEl = document.createElement('style'); var metaEl = document.querySelector('meta[name="viewport"]'); dpr = window.devicePixelRatio || 1; rem = docEl.clientWidth * dpr / 10; scale = 1 / dpr; // 设置viewport,进行缩放,达到高清效果 metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no'); // 设置data-dpr属性,留作的css hack之用 docEl.setAttribute('data-dpr', dpr); // 动态写入样式 docEl.firstElementChild.appendChild(fontEl); fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}'; // 给js调用的,某一dpr下rem和px之间的转换函数 window.rem2px = function(v) { v = parseFloat(v); return v * rem; }; window.px2rem = function(v) { v = parseFloat(v); return v / rem; }; window.dpr = dpr; window.rem = rem;
解决了: border: 1px问题 图片高清问题 屏幕适配布局问题
对于字体缩放问题,设计师的要求是任何手机屏幕上字体大小都要统一,所以我们针对不同的分辨率(dpr不同),会做如下处理
font-size: 16px; [data-dpr="2"] input { font-size: 32px; }
注意,字体不可以用rem,误差太大了,且不能满足任何屏幕下字体大小相同
一些概念
物理像素(physical pixel)
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,早操作系统的调度下,每个设备像素都有自己的颜色值和亮度值
设备独立像素(density-independent pixel)
设备独立像素(也叫做密度无关像素),可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如:css像素),然后由相关系统转换为物理像素
设备像素比(device pixel ratio)
设备像素比(简称dpi),定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式得到:
设备像素比 = 物理像素/设备独立像素
在JavaScript中,可以通过window.devicePixelRatio 获取当前设备的dpr
在不同的屏幕上,css像素所呈现的大小是一致的,不同的是1个css像素所对应的物理像素个数是不一致的
在普通屏幕下 1个css像素对应1个物理像素 在retina屏素霞,1个css像素对应4个物理像素
位图像素
一个位图像素是栅格图像(png、jpg、gif等)最小的数据单元,每个位图像素都包含着一些自身的显示信息(显示位置、颜色值、透明度等)
几个问题
retina下,图片高清问题
解决方案可以是两倍图片(@2x),然后图片容器缩小50%
缺点是 在普通屏幕下,会造成资源的浪费,图片会失去一些锐利度
最好的解决方案是 不同的dpr下,加载不同的尺寸的图片,通过css媒体查询或者是通过js条件判断都可以
还有一个就是有一个图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸
retina下,border 1px问题
可以使用hack,将y轴缩小0.5倍
或者是设置meta标签,设置viewport(scale 0.5)
<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">
页面被scale 必然会带来一些问题
多屏适配布局问题
最好的方案莫过于使用相对单位rem
基于rem的原理:针对不同手机的屏幕尺寸和dpr动态的改变根节点html的font-size大小
乘以dpr,是因为页面有可能为了实现1px border页面会缩放(scale)1/dpr,如果没有,dpr=1
除以10,为了取整,方便计算
对于动态改变根节点html的font-size,我们可以通过css做,也可以通过js做
css方式,可以通过设备宽度来媒体查询来改变html的font-size
这样的做法,没有做到足够的精确,但是够用
javascript方式,通过上面的公式,计算出基准值rem,然后写入样式
解决了: border: 1px问题 图片高清问题 屏幕适配布局问题
字体大小问题
对于字体缩放问题,设计师的要求是任何手机屏幕上字体大小都要统一,所以我们针对不同的分辨率(dpr不同),会做如下处理
注意,字体不可以用rem,误差太大了,且不能满足任何屏幕下字体大小相同