響應式之像素和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屏幕下面,圖片就縮小了一倍。看到論壇上的一些解決方案是放大一倍來設計。

相關文章
相關標籤/搜索