手机屏幕适配 原理与解决方案
什么是手机屏幕适配
一个web页做到了手机屏幕适配,是指这个页面在不同的手机上给人的视觉效果一致。这包括两个方面的内容:
- 清晰度适配:主要指位图。
- 比例适配:主要指DOM元素和文字。
逻辑像素与物理像素
要想理解什么是位图清晰度适配,先要说明一下物理像素与逻辑像素的概念
早期的屏幕,特别是PC端页面,在css中写宽度为1px,反映在屏幕上就是一个点的物理像素,也就是逻辑像素与物理像素是一致的。后来苹果推出Retina
屏之后,这个概念有了差异。你在css中写的逻辑像素,控制了较多的物理像素。
以Iphone5为例,其设备像素比
(devicePixelRatio
)为2,即是说,在这样一个手机上,以下代码
<div style="width:1px;height:1px;margin:0;padding:0;background:red"></div>
会令到屏幕上有4个物理像素(长和宽都变成2,相乘等4)的物理像素点变成红色。
更多关于物理像素和逻辑像素的概念可以自行去搜索一下。
位图适配
由于以上的差异,假如我有一张物理像素是150X150的图片,放在页面上,并且设置其宽度为150px,那么这张图片在Iphone5手机上渲染时,实际上就要把150X150个像素的点分布到300X300的物理像素区域中,虽然苹果公司有算法去计算那些缺失的区域,但是实际上还是会造成一定的模糊效果。
所以要想达到清晰的效果,最好就是准备一张300X300物理像素的图片,这样图片看起来就不会有模糊的效果了。
但是手机上带宽和流量都是珍贵的,如果用户用的是一些普通屏幕的手机,但是你还是发送了@2x
大小的图片,那就浪费了资源。所以我们需要有一些代码去检测用户手机的设备像素比
,分情况去下载不同的图片。
就目前的情况看来,大部分的手机都是设备像素比
为2的,Iphone6s/Iphone6s+是达到了3,如果你只是做移动端,可能考虑@2x
还是@3x
更加实际。但如果是响应式的网站,则还需要考虑@1x
大小的图片。
位图适配解决方案
具体到前端,我们用window.devicePixelRatio
去检测一个设备的设备像素比
。我们可以在文档载入的时候检测一下,然后给body设置一个类,比如dpr2
,然后在css中配置
pic {
background-image:url(pic.png)
}
.dpr2 .pic {
background-image:url(pic@2x.png)
}
位图适配延伸
- 只有位图有上面的问题,如果是svg等矢量图,不存在这样的问题。所以我们推荐用矢量的方式去制作网站的图标。比如 npm 的首页基本上是svg画的矢量图。
srcset
是解决清晰度问题的一个标准方案,具体可以见 https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-srcsetpicture
元素是解决清晰度问题的一个标准方案,具体可以见 https://html.spec.whatwg.org/multipage/embedded-content.html#the-picture-element
比例适配
Iphone4手机的逻辑像素是320X480,Iphone6+是414X736。同样一个宽度为320px的 div,在Iphone4上会占满整个屏幕,但是在Iphone6+中只会占一部分,其他的地方就会以背景色去填充,这会让人看起来页面不协调,比例有问题。
比例适配解决方案
- 对于宽度,可以用百分比。因为我们要达到的效果就是让人眼看起来的比例一致。但是在css中把宽度设置成百分比是相对于其包含块的宽度而言的,也就是说跟其他的元素有耦合关系,这样操作起来比较麻烦。
- 用
flex
布局,flex布局中的弹性因子就是一个分配的比例。当然这个方案也有上面的问题。 - 基于
rem
的布局 rem宽度是指html元素上的字体大小,所有元素的宽度以此为基准去设置,就会形成一个比例,而且这个比较跟你的布局无关。实用性比较大。
位图适配延伸
- 实际操作中用rem的话,还有很多细节要处理,这里淘宝有一个现成的解决方案,见 使用Flexible实现手淘H5页面的终端适配 amfe/article#17
vw
/vh
是解决比例问题的一个w3c标准方案,具体可见 http://www.w3.org/TR/css3-values/#viewport-relative-lengths
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: HTTPS 知识小结
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论