DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> WEB網站前端 >> WEB前端代碼 >> 響應式之像素和viewport
響應式之像素和viewport
編輯:WEB前端代碼     

引言

按照pc尺寸做好的網頁,在手機端打開,看起來像是pc的縮小版,東西都在只是字太小都看不清了,有什麼辦法放大呢?
於是去google一下,發現,貼了這麼一行代碼就輕松解決了:

<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…… (其實不一定都要懂,懂你需要的就不會糊塗。)

如果你不是前端,也許對上面的代碼不感興趣,那麼你很可能對下面的幾個奇怪的現象感興趣:

  • Q1: 為什麼同樣大小的字體(比如14px)或者同一個app的icon在不同的移動設備下人眼看起來的大小不一樣?
  • Q2: 電影是不是分辨率越高,在電腦上看就越清晰?
  • Q3:為什麼我用手機拍的同樣的照片,在retina屏幕下的電腦更清晰?
  • Q4: 為什麼視覺設計師為移動端設計的稿子是750px大小的?
  • Q5: 為什麼在macbook pro(retina)裡面的photoshop中打開同樣尺寸的圖片,retina中縮小了幾乎一倍?

不要暈,聽我慢慢說。

基本概念

照例,先從我自己的角度介紹一些基本概念。
一切都要從像素講起。“像素”(pixel)只存在於數碼設備顯示領域,。圖片、視屏、html中的dom元素的尺寸、iphone的設備分辨率都是可以用像素來度量的。
來一張官方iphoneSE的顯示屏介紹圖
_3

像素的種類

像素分為物理像素和設備獨立像素:

  • 設備像素/物理像素(physical pixel)
    和設備獨立像素相反,它是“依賴設備的”的像素,表示設備能控制顯示的最小單位。

更詳細點,如下圖所示,一個電子屏是有很多個固定大小的“點”組成的,可以把“點”看成是能發出彩色光的“燈泡”,每個“燈泡”只能發出一種顏色的光。當每個“燈泡”都發白光時,就是一塊純白色的屏幕;同樣的,“燈泡”按照一定的規則展示不同的顏色,就可以讓電子屏展示一幅圖啦。(為了區分,余下的文字中的物理像素都用“燈泡”來表示)
screenshot

那麼人眼能不能看到這些像素點呢?在一些電子設備上,人眼是可以感受到顆粒感的:
_5
但是在像素點小到人眼在正常情況下無法看到的情況下,屏幕是光滑的。retina屏幕就是這樣, 圖2-iphone6手機配置圖說的就是每行有1136個(燈泡)。

  • 設備獨立像素(DIP - device-independent pixel)
    顧名思義,它是獨立於設備的用於邏輯上衡量像素的單位。舉兩個例子:
    • css像素
      這個前端最熟悉,平常在開發網頁時設置字體大小、圖片顯示大小等等。用來控制元素展示的長寬,根據代碼自由定義

    • 描述位圖尺寸的像素
      平時我們在電腦上可以看到的圖片信息是這樣的:
      _6
      一張位圖圖片是由很多個大小相等的純色的色塊構成,在你用“放大鏡”放大到夠大的時候能很清楚的看得到。在photoshop中創建畫布,會首先讓你設置畫布長多少像素,寬多少像素。這裡的像素值等於色塊的個數。

    下圖是某張圖片在放大後看到的色塊。如果一張圖片尺寸是2*2,那麼它就是由4個色塊組成。這個圖片像素指的是圖片設計尺寸,不一定是真正顯示的尺寸,但是顯示尺寸等於設計尺寸時圖片是是最清晰的。它指導著屏幕裡面的“燈泡”應該展示哪種顏色。
    _7

像素的相關詞

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

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved