响应式之像素和viewport

引言

按照pc尺寸作好的网页,在手机端打开,看起来像是pc的缩小版,东西都在只是字过小都看不清了,有什么办法放大呢?
因而去google一下,发现,贴了这么一行代码就轻松解决了:css

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"/>

screenshot

为何这行代码能让字看起来和电脑差很少呢?为了搞懂这行代码的意思,又去google,可是立马被一大堆的概念给弄糊涂了。px,pt,dpi,ppi,dip,dpr…… (其实不必定都要懂,懂你须要的就不会糊涂。)html

若是你不是前端,也许对上面的代码不感兴趣,那么你极可能对下面的几个奇怪的现象感兴趣:前端

  • Q1: 为何一样大小的字体(好比14px)或者同一个app的icon在不一样的移动设备下人眼看起来的大小不同?
  • Q2: 电影是否是分辨率越高,在电脑上看就越清晰?
  • Q3:为何我用手机拍的一样的照片,在retina屏幕下的电脑更清晰?
  • Q4: 为何视觉设计师为移动端设计的稿子是750px大小的?
  • Q5: 为何在macbook pro(retina)里面的photoshop中打开一样尺寸的图片,retina中缩小了几乎一倍?

不要晕,听我慢慢说。android

基本概念

照例,先从我本身的角度介绍一些基本概念。
一切都要从像素讲起。“像素”(pixel)只存在于数码设备显示领域,。图片、视屏、html中的dom元素的尺寸、iphone的设备分辨率都是能够用像素来度量的。
来一张官方iphoneSE的显示屏介绍图
_3ios

像素的种类

像素分为物理像素和设备独立像素:web

  • 设备像素/物理像素(physical pixel)
    和设备独立像素相反,它是“依赖设备的”的像素,表示设备能控制显示的最小单位。
    更详细点,以下图所示,一个电子屏是有不少个固定大小的“点”组成的,能够把“点”当作是能发出彩色光的“灯泡”,每一个“灯泡”只能发出一种颜色的光。当每一个“灯泡”都发白光时,就是一块纯白色的屏幕;一样的,“灯泡”按照必定的规则展现不一样的颜色,就可让电子屏展现一幅图啦。(为了区分,余下的文字中的物理像素都用“灯泡”来表示)
    screenshot
    那么人眼能不能看到这些像素点呢?在一些电子设备上,人眼是能够感觉到颗粒感的:
    _5
    可是在像素点小到人眼在正常状况下没法看到的状况下,屏幕是光滑的。retina屏幕就是这样, 图2-iphone6手机配置图说的就是每行有1136个(灯泡)。chrome

  • 设备独立像素(DIP - device-independent pixel)
    顾名思义,它是独立于设备的用于逻辑上衡量像素的单位。举两个例子:
    • css像素
      这个前端最熟悉,日常在开发网页时设置字体大小、图片显示大小等等。用来控制元素展现的长宽,根据代码自由定义浏览器

    • 描述位图尺寸的像素
      平时咱们在电脑上能够看到的图片信息是这样的:
      _6
      一张位图图片是由不少个大小相等的纯色的色块构成,在你用“放大镜”放大到够大的时候能很清楚的看获得。在photoshop中建立画布,会首先让你设置画布长多少像素,宽多少像素。这里的像素值等于色块的个数。app

      下图是某张图片在放大后看到的色块。若是一张图片尺寸是2*2,那么它就是由4个色块组成。这个图片像素指的是图片设计尺寸,不必定是真正显示的尺寸,可是显示尺寸等于设计尺寸时图片是是最清晰的。它指导着屏幕里面的“灯泡”应该展现哪一种颜色。
      _7dom

像素的相关词

  • ppi (Pixels Per Inch)
    也叫像素密度,所表示的是每英寸所拥有的像素数量。密度越高,拟真越强。移动设备一般会给出对角线的长度(单位英寸),和长*宽的分辨率,因此根据公式能够算出ppi:
    _8

    同理,若是只给出了设备长(单位英寸)和长度分辨率(单位像素),也一样能够算出来。

  • dpi (Dots Per Inch)
    这是和ppi容易混淆到一块儿的概念。指打印设备每英寸印刷出来的点有多少个,同一张图片打印出来和在电脑上看到的清晰度就不必定相同。由于不影响咱们理解,有一些博客又喜欢混用,做为只跟电子屏打交道的前端开发,认为各大博客上的dpi=ppi就好。

  • dpr (device-pixel-ratio: Number of device pixels per CSS Pixel)

    dpr能够用window.devicePixelRatio获得,是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。
    公式表示就是:window.devicePixelRatio = 物理像素 / dips

    你们一般指的dpr是个固定值: dpr的值表示在理想布局宽度(ideal viewport)里,使用多少个物理像素来渲染一个设备独立像素

    在ios中,dpr一般是1,2,3;可是在android中,ideal viewport会根据浏览器本身的喜爱变化,甚至会是小数。如今andorid注重高分辨率,不少都达到3了。

Viewport

终于讲到上面的meta标签,name是viewport。 那么什么是viewport?

viewport是视口、视窗的意思,Peter-Paul Koch 大神将其分为layout viewport,visual viewport,ideal viewport三种,三种的单位都是相对像素。在这个meta标签中指的是layout viewport。

  • ideal viewport 理想视图

    • 它不是一个真实存在的视图,而是开发者指望的视图。在这个视图中,文字和图片无论在何种分辨率下(不管是pc仍是移动端)在肉眼看起来均可以保持差很少大小。在响应式设计的年代,确实只要保证这一点就够了。
    • 不一样设备"理想视图"的宽度有不一样的大小,安卓的设备种类比较多,只列出一种参考下。
      screenshot
    • 一些设备上,ideal viewport宽度能够用screen.width获取;另外一些设备上须要screen.width除以window.devicePixelRatio

剩下的两种视图,我看了不少博客都以为晕晕的。最后发现用<html></html> 来切入很适合用来理解。

在网页设计里,若是用百分比定义块状元素的尺寸,那么元素的尺寸等于其父元素乘以该百分比。一张网页中全部标签的父元素是<html></html>,那若是html的宽度也用百分比定义,html的父元素又是什么呢?没错,就是“渲染视图”(layout viewport)。

  • visual viewport 视觉视图

    • 从好懂的视图讲起,“视觉视图”的宽度就是指你看到的浏览器或者app的webview中可视区域的宽度。他的值颇有用,能够用来推算1个css像素在当前页面等价于多少里面。很简单,把页面分红宽度值那么多份就好。
    • 举例:好比视觉视图的宽度为6px;那么2px的字就是这么大。
      screenshot
      因此说,为了让手机上的字和电脑上大小差很少,咱们但愿visual viewport的宽度等于ideal viewport。
    • visual viewport宽度能够用window.innerWidth获取
  • layout viewport 渲染视图

    • <html></html>的父元素,网页内容在其基础上进行渲染,因此叫“渲染视图”。
    • 和visual viewport的关系:
      • 在pc上,dom树中超出的layout viewport的部分(网页中有元素任性的比渲染视图还宽)不会算入visual viewport。
        • 网页缩放倍率为1或者缩小时,layout viewport宽度=visual viewport宽度;。
        • 网页放大时,layout viewport宽度>visual viewport宽度(和手机同样,可参考下图)。
          screenshot
      • 在移动端比较复杂,不一样浏览器/设备有不一样的表现。
        • 一部分浏览器/设备,dom树中超出的layout viewport的部分不会算入visual viewport。
        • 另外一部分浏览器/设备,dom树中超出的layout viewport的部分会算入visual viewport,此时visual viewport宽度 > layout viewport(亲测摩托罗拉的chrome浏览器就是这样)。
        • 在网页设计中,咱们不但愿有滚动条,一般会保证没有元素超出<html></html>,或者把超出的部分hidden掉,因此暂时能够不用考虑超不超出的问题。
      • 综上,为了让在宽度有限的设备上看到layout viewport的全部内容,咱们让layout viewport的宽度等于visual viewport,设置页面缩放比例为1便可.
      • layout viewport宽度能够用document.documentElement.clientWidth获取。

文章开头说的字在手机上变小的状况,是由于手机面世初期,不少网页都是针对pc端设计的.宽度至少在900px以上吧。这样放在手机上由于容器变窄,文字和图片会互相挤压。为了解决这个问题,不少手机浏览器会在默认状况下,设置visual viewport为一个较大的值,好比iphone6和摩托罗拉t40上是980px。这样,pc上的页面基本就能够不变形的展现在手机上,只是字很小。
现在不少网页都是响应式开发,其实已经不须要这个默认值了。

文中开头的代码是常见的移动端开发会加入的代码,可是在pc端是不生效的。最后解释一下meta标签中的每个属性:

  • width: 设置layout viewport的宽度。可设置为为一个正整数(单位px),或字符串"width-device"(等于设备宽度/理想宽度)
  • initial-scale: 设置页面的初始缩放值,为一个数字,能够带小数。当initial-scale为1时,不论是否设置width,layout viewport宽度=visual viewport宽度=ideal viewport宽度。iphone6上就是375px。
  • minimum-scale: 容许用户的最小缩放值,为一个数字,能够带小数
  • maximum-scale: 容许用户的最大缩放值,为一个数字,能够带小数
  • user-scalable: 是否容许用户进行缩放,值为"no"或"yes", no 表明不容许,yes表明容许

解答问题

  • Q1: 为何一样大小的字体(好比14px)或者同一个app的icon在不一样的移动设备下人眼看起来的大小不同?
    答:其实这个问题等价于一个css像素在两个设备中分别等价于多少英寸。若是网页是在ideal viewport下,能够推理出一个公式:每一个物理像素等于1/PPI()英寸),在ideal viewport下,DPR表示1个css像素由几个物理像素组成。所以,获得公式:
    (1/PPI)* DPR = DPR/PPI
    举个例子:iphone6-PPI为326,DPR为2,DPR/PPI约等于0.0061;iphone6S-PPI为401,DPR为3,DPR/PPI约等于0.0075;因此iphone6s上的app和字比iphone6大哦。
    一般,设备显示屏越大,一个css像素表明的物理尺寸须要大一点。由于人眼会离大屏幕的比较远,离小屏幕的比较近。虽然物理尺寸不同,可是人眼感受起来是差很少大的。

  • Q2: 电影是否是分辨率越高,在电脑上看就越清晰?
    答:不是。每一个设备拥有的“灯泡”(设备像素)是固定的。若是电影的分辨率大于设备拥有的“灯泡”,就表明着要用1个“灯泡”来显示多个图像像素。可是一个“灯泡”只能发出一种光,最好是让一个“灯泡”显示一个图像像素。因此之后下电影下适合的分辨率就好啦,不然也是浪费掉了。
  • Q3:为何我用手机拍的一样的照片,在retina屏幕下的电脑更清晰?
    答:PPI越高,画面越精细。当图片的显示大小小于它实际的分辨率(数码设备发展很快,随随便便一张图就能够很大的分辨率,因此通常都是小于的),4 * 4的照片通常设备只能用2 * 2的“灯泡”来渲染,而retina的设备能够用4*4的来渲染,因此就更清晰啦。同理也能够应用与上面电影的问题,retina能够播放更大分辨率的电影。
  • Q4: 为何视觉设计师为移动端设计的稿子是750px大小的?
    答:如今移动端的页面会基于宽度为750px的画布进行设计,是根据iphone6的设备分辨率来设计的。虽然iphone6上网页设计出来只有375px大小,可是为了充分利用每个“灯泡”,画面更精细,须要用750px的画布来设计。
  • Q5: 为何在macbook pro(retina)里面的photoshop中打开一样尺寸的图片,retina中缩小了几乎一倍? 答:补充一下,这里的场景是图片都不放大的状况下。 在不放大的状况下,默认photoshop中一个“灯泡”渲染一个图片像素。由于retina屏幕的像素密度更大,在dpr为2的retina屏幕下面,图片就缩小了一倍。看到论坛上的一些解决方案是放大一倍来设计。

相关文章
相关标签/搜索