深入了解viewport、css像素、设备像素、屏幕尺寸、屏幕分辨率、媒体查询、响应式和自适应

都说前端坑多,这不,最近只是想研究viewport,却产生了N多问题:

  • 宽度单位我是用百分比还是em?还是rem?区别呢?绝对长度单位?相对长度单位?
  • px、pt、pc、sp、em、rem、dp、dip、ppi、dpi、ldpi、mdpi、hdpi、xhdpi、xxhdpi……这些有什么区别?他们之间如何转化计算的?
  • 什么是屏幕尺寸、屏幕分辨率、屏幕像素密度、设备像素、css像素? 浏览器窗口大小和设备大小和分辨率大小啥区别啊?
  • 如果做移动适配,到底我应该按照多大尺寸制作?320、640还是720?
  • 如果我按640的尺寸重构后,是不是还需要再做其他尺寸来适配不同大小的屏幕?
  • 为什么我要按照640的大小来设计页面而不是其他尺寸?
  • 做移动端适配,如果我按给元素赋予固定的像素值640,但为什么在不同的手机里看起来都差不多,不需要另外去适配?
  • viewport又是什么?media媒体查询又是什么?js判断又是什么?三者区别?
  • 写一个css还是写多个css?
  • 什么是响应式网站,自适应又是什么鬼?两者有何却别和联系?百分比宽度布局和流式布局和前者的关系?
  • 既然响应式这么流行,为何大的网站淘宝、百度等没有去做,而是单纯开发了一个移动站?这里面有那些坑需要避开?

好了,上面是我们的问题,虽然心情复杂,但我们还是从最基础的来捋一捋吧。

什么是响应式网站,自适应网站?两者有何却别和联系?百分比宽度和流式布局和前者有何关系?

  • 历史发展

在很早之前,我们上网设备还不多,屏幕也不多,显示器分辨率也就那几个。那个时候,我们的网站几乎都设计的是固定宽度的尺寸,比如最多见的就是800px、850px、960px。这样本没有问题,也少有人在人电脑还未普及的时代去考虑手机的问题,至少那不是个主要矛盾的点。后来随着个人笔记本普及,上网设备增多,显示器分辨率也越来越多,这时候,这种固定宽度的页面问题就凸显了,有的pc分辨率都能达到2000像素了,再用960的,看上去就显得很小,这只是其中一个问题,如果把宽固定写死了,那对于笔记本用户来说又是问题,笔记本的分辨率那时落后pc的,如果用户主动缩小窗口,或笔记本分辨率太低,那么窗口缩小后内容就会被遮挡住,还会出现横向滚动条,拖动滚动条才能显示全部布局,这种绝对固定宽度的布局被称为是静态布局(StaticLayout),也有叫固定布局(Fixed Layout)的。只不过这个问题在当时并没有成为很严重普遍急需解决的问题,因为伴随而来的是各浏览器大战,IE被chrome、firefox、Oparo等赶下神坛,大家都开始向W3C标准趋近,因为浏览器的增多,催生出了针对浏览器的css hack技术的出现,开发者们忙于兼容各种浏览器。在这个期间实际上已经有了针对各设备适配的解决方案了,只是未成为主流,虽然不是主流,但不代表当时就没有人去用。当时出现的新布局方式叫自适应布局(Adaptive Web Design,简称AWD)。在当时,大多指的就是宽度自适应布局。在这种新思想下,又出现了两派的具体解决方案:百分比宽度布局流体式布局(Fluid Layout)。在当时,大家都还没有响应式布局的概念,即便伟大的谷歌也没有,但是却出现了一个新的词--渐进增强。渐进增强出现后,另一个词优雅降级也随之出现了。关于两个词的概念请自行google和wiki,这里只是举个典型的例子:gmail和qqmail。这两个都是百分比宽度布局,都属于自适应布局,但有区别。qqmail就是css hack的完美体现,你用任何一个浏览器,几乎可以看到同一个样子的邮箱,为的是用户体验统一。gmail则使用了渐进增强,你的浏览器越新越强,你看到的效果就越好,为的是用户体验增强。再后来,Google发布了android,移动互联网爆发,html5标准发布。互联网大战从PC打到了手机。手机虽然屏幕变小了,但是却提供了更丰富的功能,用户要求不断提高,网站更加看重的是用户体验了,所以,谷歌式的渐进增强被广泛认可,结合自适应的思想,出现了响应式布局的概念(2010年由Ethan Marcotte提出),如果说以前这个虽有人用但非主流的话,那么在移动互联网(流量转移)的冲击和推动下,再也没有企业敢去忽视它了,而另一个将响应式布局推上主流的重要原因是twitter开源了bootstrap。所以,在自适应和响应式中,响应式布局成为了最终的解决方案胜出者。这也是现在很少有人去提自适应的原因,但如果从广义上讲,响应式布局实际上就是更好、更机智、更灵活的去实现自适应,他们都算是一种弹性布局。再通俗点讲响应式重在于「响应」它会随着设备属性(如宽高)的变化,网页也跟着变化。

  • 静态式、自适应、流体式、响应式布局的对比
    • 布局特点
      静态式布局:窗口缩小后内容被遮挡时,拖动滚动条显示布局。不管在哪种设备,哪种浏览器上浏览都是一个样。移动设备上则显示太小或不全。
      自适应布局:分别为不同的屏幕分辨率设备设计不同的样式布局,相当于多个静态布局组成的一个系列合集,每个静态布局对应一个屏幕分辨率范围,页面通过百分比自动适配设备屏幕分辨率和可视窗口大小,当可视窗口改变时,不会出现横向滚动条,UI,图片,文字会自动缩放,元素内容、布局、交互方式基本不变。
      流体式布局:属于自适应的一个子集,也是通过百分比自动适配设备屏幕分辨率和可视窗口大小,不同于百分比自适应的是随着窗口大小的改变,页面的布局会发生小的变化,可以进行适配调整,这个正好与自适应相补。
      响应式布局:分别为不同的屏幕分辨率设备设计不同的样式布局,并应用流式布局的理念,每个弹性布局分别对应一个屏幕分辨率范围,即页面元素宽度随着窗口调整而自动适配,元素位置、大小、内容会随着改变,甚至某些元素会被隐藏掉,显示效果和交互方式都会发生变化各不相同,所谓的效果即特效。可以理解成自适应布局和流体布局的结合,也属于自适应的一个进化版的子集。

    • 实现方式
      静态式布局:使用绝对宽高,PC居中布局,移动则另建站点,以m.为二级域名。
      自适应布局:使用宽度百分比,通过服务端脚本实现不同终端输出不同的html/css/js来适配,保证所有设备上的显示效果基本一致。
      流体式布局:利用宽度百分比,单位rem和viewport,浏览器文档流浮动来实现超过宽度,自动流动布局。
      响应式布局:使用css3 media query媒体查询断点或js判断和控制html改变布局,并使用宽度百分比,单位rem,流式布局fluid grids,自适应图片/视频等内容来更好的把控布局,但在开发之初就考虑到一个模块在所有设备下的布局显示情况。

    • 存在缺点
      静态式布局:pc端在浏览器可视窗口小于固定宽度或屏幕分辨率太低时:1、网页内容会被遮挡;2、出现滚动条很丑;如果没有针对移动端做单独做适配站点的话,在移动设备上还会挤在一起,内容显示太小或不全,需要手动缩放或移动来查看其它内容,有的布局也会乱掉,如果pc页面就一屏的,移动显示还会下面留白,体验很差。
      自适应布局:自适应是基于断点而使用的静态布局集,一旦页面被加载就无法再进行自动适应,自适应会自动检测屏幕的大小来加载适当的工作布局,也就是说,需要一个一个设计多种常见的屏幕布局(320、480、760、960、1200、1600),而且如果内容较多,页面就会很长,阅读就很费劲。
      流体式布局:流式布局虽然可以让各种屏幕都适配,但是显示效果极其不好,因为只有几个尺寸的手机能够完美的显示出视觉设计师和交互最想要的效果。这种都是通过百分比定义宽度,高度大都采用px固定。所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度还是和原来一样,实际显示就会被拉伸变形,尤其是图片看起来非常的不协调,这就是流式布局的最致命的缺点。后来有些就采用之前pc端的静态布局方法,通过把页面设置成固定320的宽度,超出部分留白的做法,这样做视觉,前端和设计都开心,设计再也不用被流式布局限制自己的设计灵感了,前端也不用在搞坑爹的流式布局。但这种解决方案也存在一些问题,例如在大屏幕手机下两边不仅是大量留白的,看起来页面也会特别小,操作的按钮也很小,也不是最佳解决方案。后来则由响应式来解决此类问题了。
      响应式布局:1、响应式设计仅是改善移动体验并没达到最优化,因为有些元素会被隐藏,和单纯针对移动端设计独立手机网站对比差距很大。2、响应式设计并不利于SEO排名优化。3、响应式网站无法区分移动端,浪费流量,加载耗时长。因为它是把某些内容隐藏或缩小了,但对浏览器来说隐藏的内容同样会被加载,低分辨率设备会加载高质量的图片或者视频,导致响应式网站加载的内容相比非响应式网站会增加20-50%,速度慢,对于移动端还有2G、3G的用户来说就是灾难,每延长0.4秒就会流失5-9%的用户。4、响应式对于ie7,8浏览器简直是悲剧,ie9,10表现也差强人意。响应式一般都运用了很多html5新特性,而这些新特性只有高级的现代浏览器才有出色表现。5、工作量大,维护难,体验不灵活。

    • viewport
      静态式布局
      自适应布局
      流体式布局
      响应式布局

    • 断点(break point)
      静态式布局
      自适应布局
      流体式布局
      响应式布局

    • SEO
      静态式布局
      自适应布局:自适应网站不容易聚集网站权重,但可以通过重定向进行聚集权重。
      流体式布局
      响应式布局:响应式网站容易聚集网站权重,容易把移动端的权重与PC端的权重叠加,但并不利于SEO,因为用户在不同终端的搜索习惯不同,搜索引擎对移动网站和PC网站的关键词处理策略和排名机制都是不相同的。而响应式方案,不同终端访问到的代码是一样的,无法设置不同的关键词,针对性的优化。

    • 开发难度
      静态式布局
      自适应布局:自适应网站开发起来比较既复杂(不同屏幕的适配控制)又简单(独立于PC端),但是容易维护与调试(只有移动端的处理事件)。
      流体式布局
      响应式布局:响应式网站开发起来比较既简单(只需通过媒体查询来调整)又复杂(与PC端网页元素耦合度大),但是不容易调试与维护(绑定了移动端与手机端的处理事件)。

    • 用户体验
      静态式布局
      自适应布局:自适应网站保证移动端更友好的体验。
      流体式布局
      响应式布局:响应式网站保证PC端与移动端的一致性,流式布局。

    • 页面性能
      静态式布局
      自适应布局:自适应网站只有移动端的布局与样式(内容少),下载到浏览器立刻显示,所以性能快。
      流体式布局
      响应式布局:响应式网站不仅有移动端的布局与样式,还有PC的布局与样式(内容多),下载到浏览器之后进行网页布局调整再显示,所以性能慢。当然,响应式网站也有提高性能的方法,就是针对屏幕加载不同的媒体查询样式,选择性加载资源。但是性能依然不如自适应网站。

  • 响应式和自适应的区别联系
    响应式(Responsive)和自适应(Adaptive)的关系很密切,经常二者是互通的。虽然互动但却没有必然关系。什么意思呢?就是自适应页面可以是响应式的,也可以不是响应式的。响应式页面可以是自适应的,也可以是不自适应的(固定宽的)。自适应强调「不写死宽度」,响应式强调「响应」。
    自适应主要针对的是移动端来说的,它往往是应对一个新需求或情况的被动变化,它的目的是让页面在其他各个设备上浏览时,布局能保持一致性,不会因为屏幕宽窄大小而影响视觉和响应效果,从而更友好的展示自己。它的特点是在不同的屏幕分辨率下,页面元素内容和布局不随窗口大小的调整发生太大变化,宽度、图片保持自适应,内容不会被遮挡不会删减内容,不会出现滚动条,避免出现需要用手放大,拖拽浏览的情况。
    响应式主要针对的是web端来说,它通常意味着对待任何变化,反应更积极更快更灵活更主动更具可读性,相当于针对不同分辨率量身打造的不同布局,在布局中应用流式布局的理念,即页面元素宽度随着窗口调整,布局和内容也随着自动调整来适配,内容元素和原网页相似,有些甚至会被隐藏掉,布局则根据设备不同,窗口大小,分辨率而不同,为的是以最好的姿态流畅自如的展示自己,响应式可以理解为是自适应的一个进化版的子集。

RWD和AWD在断点( break point)上的区别:
RWD采用流体+断点,在断点之间,页面依然会随窗口大小自动缩放(通过fluid grid),直到遇到断点改变界面样式布局甚至内容。RWD一般来说需要在网页设计初期就开始(通常采用mobile first策略),所以旧的网站要做RWD很可能要完全重建。
AWD 只在针对几种分辨率(如320,480,760,960,1200,1600px)进行优化,在断点之间的自动过渡比较少。而AWD 则采用保留现有桌面网站(desktop version)而对于更小的分辨率做针对性的优化(适应),减小重构的成本。

在下图中可以看到,Responsive design中网页和屏幕分辨率的关系是一对多的,一套网页适应多个设备。而Adaptive design中网页和屏幕分辨率的关系则是一一对应。



因此Responsive design相对来说灵活性更高,但是相应的每次的载入内容会比较多。而只针对某一类或某几类分辨率设计响应网页大小Adaptive design的优势就在于减少载入的等待时间,提高网页的响应速度,如下图:


从外观上很难分辨,但他们自己运行机理不同,RWD是主动式的响应设计,AWD是被动式的响应式设计,RWD不管用户使用的是什么设备都是在服务器把数据推送到浏览器后,脚本或CSS自行侦测屏幕大小后执行对应的样式表内容,并且一直通过本地脚本在监听屏幕大小的变化,随时做出样式响应的变化,所以是主动的。但AWD是用户通过浏览器发送请求后,服务器根据请求中夹带的用户设备设备信息做出判断,调用已经在服务器里准备好的,适应对应设备样式文件+HTML内容+JS,返回给浏览器以这种方式响应不同设备。

  • 移动端适配应该选择那种方式?

如果我们要去做移动端,一般会有三种选择:响应式设计、独立手机站、独立app。独立手机站的体验好,但由于独立手机站的开发和维护成本都很大,数据无法打通不说,还需要更多的编辑维护内容。而对于体验更好的独立开发APP来说,成本则更大,而且对很多小企业来说根本没必要,开发出来后,推广下载量又是个问题。所以,如果企业属于小企业,业务类型简单,只是企业站或博客类做适配则推荐响应式。如果是大企业,业务复杂尤其是那些电子商务型的,采用响应式则工作量巨大,维护难,很多页面都很老旧,还需要重构,这种则不如直接针对移动做个独立站点,启用二级域名M来解决,反而更省成本,提高效率。这也是国内很多大站淘宝,qq,百度等没有做响应式的原因。

一是看应用场景,二是看如何设计“响应式”方案。简单、轻量的页面直接用media query实现响应性就很好。比如blog、小型企业站之类。现在的CSS框架基本都具备响应性。但请注意响应式不仅仅是响应式布局。对于大型站简单用media query是远远不够的。于是在同一个controller层上,识别UA,渲染不同版本的模板,组合相应的静态资源。这也算是响应式。开发及维护成本明显提高。当各个版本间的差异很大时,维护成本很可能会大到无法接受。即便分开做,架构上也要调整,后端服务化,应用层app化。根据不同公司的技术特点,调整的成本也难讲是否可行。对于大型站,分开做更清晰,同时用响应式组件解决复用、功能同步的问题。比如原生的select控件,在pc、android、ios下有不同的呈现和交互,但用法是一致的。同理,通用的业务组件也可以这样做。web component普及后最终能解决这个问题。现在这个阶段,可以设计类web component的方案。另外,从优化角度,是否分开做,图片之类静态资源的响应性都是有必要做的。总之,根据场景响应式可以从各种层面,各种粒度上做。这是现代web开发的特点。

总结:推荐开发自适应网站,追求性能与用户体验。(大多数的互联网公司都是web PC端与移动端分离的)
响应式网站不适合开发一些比较复杂的网站。(涉及一些动画交互效果,页面元素过多)
建议开发一套响应式电脑网站(过渡到平板端,不过渡到手机端)和开发一套响应式手机端网站(过渡到平板端以下的尺寸,不过渡到平板端)


移动和桌面设计的差别远不止是布局问题。只要有足够的编程量,这些差别是可以通过响应式设计来解决的。事实上,你可以认为如果一种设计不能兼顾两种平台的主要差别,就不能算是合格的响应式设计。但是,如果确实想要处理好平台间的所有差异,我们就回到了原点:进行两种不同的设计。


复杂的页面,前端经常变化的页面,响应式还是算了吧,像我们针对设备不同界面的传统搞法确实屌丝,冗余代码无力吐槽了,但是维护起来确实方便些,不至于bug补好东墙,凿穿西墙,响应式遇到页面变更时常常半夜电话响不停,响应式,影响夫妻和谐,你造吗;


但如果页面复杂一点的,那信息取舍就是个难题。
需求变更频繁一点的,设计的延续性就是个难题。
在性能决定一切的当下,移动网络体验必须和闪电一样快。迅速、实用、兼容的体验对所有移动设备都是挑战。当你使用响应式设计时,这些挑战就存在。pc和移动分开性能真比响应式好。一个核心两套模板就行,别看那些手机配置多高,实际和电脑真没法比,响应式代码真的复杂了。其次手机下载那么多文件,网络成问题,我最近才升4G,用2G的大有人在。客户体验很重要。不要只知道满足程序员自己的技术追求。援引Ethan Marcotte的话:“最重要的是,响应式网页设计的初衷不是要取代移动网页。”响应式设计从来不是意味着要解决“性能”,然而,相信它能解决你所有问题,这大错特错。如果我们能使用一些其他的技术,就可以实现获得响应式设计好处的同时,同时又不影响移动设备的性能,这是比较理想的。


响应式布局有可能造成冗余的代码较多,对研发的要求也更高,比如如何更好地让图片,适配,UI动画自适应各种布局。

大站还是要考虑数据计算和承载的问题,会对桌面和移动端输出不同数据,减轻压力。

综上几点就解释了为什么国内很多大企业都没使用响应式,不论是淘宝、天猫、京东、唯品会,还是腾讯、百度、新浪、360都采用分开建设电脑端和移动端网站的方式。当然,大站里面也有响应式做的好的,主要是网站类型比较适合和网速等都有关系,比如:thenextwebdribbbleaol等。

设置viewport进行缩放:
天猫的web app的首页就是采用这种方式去做的,以320宽度为基准,进行缩放,最大缩放为320*1.3 = 416,基本缩放到416都就可以兼容iphone6 plus的屏幕了,这个方法简单粗暴,又高效。

http://www.cnblogs.com/qieguo/p/5421252.html
https://www.zhihu.com/question/38065402
https://www.zhihu.com/question/25836425
http://mediaqueri.es/
http://www.resizer.cn/
http://alistapart.com/article/responsive-web-design
http://www.shejidaren.com/principles-of-responsive-web-design.html
http://qietuwang.baijia.baidu.com/article/75296
http://www.ruanyifeng.com/blog/2012/05/responsive_web_design.html
http://www.alloyteam.com/2015/04/zi-shi-ying-she-ji-yu-xiang-ying-shi-wang-ye-she-ji-qian-tan/
http://www.codingserf.com/index.php/2014/07/responsive-and-mobile-1/
http://www.passquan.cn/node/136%201.10%E4%B8%AA%E8%87%AA%E9%80%82%E5%BA%94%E7%BD%91%E7%AB%99%E8%AE%BE%E8%AE%A1TIPS
详解
viewport即网页的视窗区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏、状态栏、滚动条等等之后用于看网页的区域。对于pc端并没有什么问题,不设置也没关系。但移动互联网浪潮来了后,对于早期的未针对手机浏览器做优化的页面如何在手机浏览器上正确显示同时不破坏网页原有的结构布局就成了一个问题。因为移动设备的屏幕都不是很宽,所以那些为桌面浏览器设计的网站放到移动设备上显示时,必然会因为移动设备的viewport太窄,而挤作一团(如下图左图所示,几乎看不清内容),甚至布局什么的都会乱掉。为何会这样呢?因为css中的1px并不是代表屏幕上的1px(这个问题下面有扩展)。为解决这个问题,就引入了viewport 的元标签(viewport标签最初为apple所推行,适用于IOS中的Safari,后各大浏览器厂商陆续采用了它)。viewport就是手机端浏览器(也可能是一个app中的webview)的一个虚拟“窗口”,而这个虚拟的窗口(viewport)并不局限于浏览器可视区域(你所能看到的)的大小,它可大于或小于手机浏览器的可视区域,考虑到移动设备的分辨率相对于桌面电脑来说都比较小,所以为了能在移动设备上正常显示那些传统的为PC浏览器设计的网站,移动设备上的浏览器都会把自己默认的viewport设为980px或1024px(也可能是其它值,这个是由设备自己决定的),也就是说,一般手机默认viewport是大于可视区域的。默认情况下,用户可以通过手动平移和缩放来看网页的不同部分。但随之带来的副作用就是浏览器会出现横向滚动条,很丑。


而对于针对移动端浏览器优化过后的viewport又该是多宽呢?

所以,这里引申出来viewport在移动端的三个概念:

  • visual viewport
  • layout viewport
  • ideal viewport
    这三个是分别代表什么意思呢?

visual viewport:手机物理屏幕上浏览器可视区域的大小。就是当前显示给用户可以看到内容的窗口,它包含网页的所有内容,可以全部或者部分展示给用户,你可以拖动或者放大缩小来看网页的其他内容。简单说就是visual viewport==屏幕显示器的物理像素==浏览器可视区域(同样尺寸的屏幕,像素密度大的设备,硬件像素会更多),visual viewport的宽度可以通过window.innerWidth来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。

layout viewport:移动设备上浏览器的默认布局区域。这个layout viewport的宽度可以通过document.documentElement.clientWidth来获取。
下图是一些移动设备上浏览器的默认viewport宽度:

常见移动设备默认viewport宽度

  • ideal viewport:能完美适配移动设备的理想viewport。即用户无需缩放和横向滚动条就能正常的查看网站的所有内容,而且显示的文字和图片的大小在任何分辨率下,任何密度屏幕下,均可以正常显示,不会缩小看不清。ideal viewport并没有一个固定的尺寸,不同的设备有不同的ideal viewport。所有的iphone的ideal viewport宽度都是320px,无论它的屏幕宽度是320还是640,也就是说,在iphone中,css中的320px就代表iphone屏幕的宽度。但是安卓设备就比较复杂了,有320px的,有360px的,有384px的等等,关于不同的设备ideal viewport的宽度都为多少,可以到http://viewportsizes.com去查看一下,里面收集了众多设备的理想宽度。

三种viewport中,ideal viewport是最适合移动设备的viewport,ideal viewport的宽度等于移动设备的屏幕宽度,只要在css中把网页的宽度设为ideal viewport的宽度(单位用px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为100%的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。

大部分4.7-5寸设备的viewport宽设为360px;5.5寸设备设为400px;iphone6设为375px;ipone6 plus设为414px。

https://www.zhihu.com/question/20628050?rf=24334181
http://blog.jobbole.com/44319/
http://www.css88.com/archives/5975
http://tgideas.qq.com/webplat/info/news_version3/804/7104/7106/m5723/201509/376281.shtml
http://www.cnblogs.com/2050/p/3877280.html
https://segmentfault.com/a/1190000002685485
https://developer.mozilla.org/zh-CN/docs/Mobile/Viewport_meta_tag

推荐阅读更多精彩内容