天天看點

Viewport 等比适配始末

viewport的大小決定了,css中的設定多少像素能剛好占滿螢幕。例如,viewport=320,那麼設定div的寬度為320px,則div剛好能占滿螢幕

移動裝置中1px不等于1個實體像素

現如今,移動裝置多已經采用高倍屏,像素分辨率(實體分辨率)要比邏輯分辨率高,下表為iphone分辨率資料

型号 像素分辨率 邏輯分辨率 倍率
iphone5 640*1136 320*568 2
iphone6 750*1334 375*667 2
iphone6 plus 1242*2208 414*736 3

可以使用如下代碼來讓viewport寬度等于邏輯分辨率寬度(width=device-width)

這個時候1px是不等于一個實體像素的,而是等于倍率個實體像素,如果我們在改變viewport的值,可以讓css中的1px代表的實體像素有更多的可能

利用meta标簽對viewport進行控制

屬性名 說明
width 設定viewport的寬度,為一個正整數,或字元串"width-device"
initial-scale 設定頁面的初始縮放值,為一個數字,可以帶小數
minimum-scale 允許使用者的最小縮放值,為一個數字,可以帶小數
maximum-scale 允許使用者的最大縮放值,為一個數字,可以帶小數
height 設定viewport的高度,這個屬性對我們并不重要,很少使用
user-scalable 是否允許使用者進行縮放,值為"no"或"yes", no 代表不允許,yes代表允許

width和scale都可以用來設定viewport的值

viewport = width;
viewport = idea viewport /scale;複制代碼
           

在網上搜尋到一種說法:

當同時設定了width和scale的時候,viewport的取值等于上面兩個等式計算之後得到的值大的那一個,我們常常會看到width和initial-scale同時設定的情況,那完全是為了相容各個浏覽器

然而,嘗試之後,發現那個說法并不是很準确。如果隻設定width不設定scale,在width的值大于裝置邏輯分辨率的時候,内容沒有如願的充滿整個裝置,而是出現橫向滾動條(即沒有主動縮放),有點打破開篇總結的結論的意思,那真的是非常令人沮喪的。是以說:

同時設定width和scale,讓它們通過公式計算得到的viewport的值一樣,是最為安全的,也不會讓人産生疑惑

用viewport來解釋兩個靈異現象

  • 同樣的裝置,同樣是設定了border = 1px,為什麼别人的網頁上的線看起來比我的細? 現在很好解釋了,通過設定viewport,可以改變css中的1px用多少實體像素來渲染,設定了不同的viewport,當然1px的線條看起來粗細不一緻。(處女座的設計,還真有可能會為了你這1px的線條看起來太粗而找你麻煩)
  • 為什麼同樣是1px的線,在同一個裝置的同一個網頁中,不同位置看到的粗細不一緻?如下圖所示,倘若在css中的1px=1.5個實體像素,那麼在頁面中的不同位置,1px的線跨越的實體像素有可能是兩個,也有可能是三個,用3個實體像素表示的線肯定是要比用兩個實體像素表示的線要寬的(雖然差異不明顯)。解決方案:設定viewport=裝置的實體分辨率,讓1px=一個實體像素

viewport.png

使用viewport來實作等比适配

倘若我們要做到把設計圖根據裝置的寬度等比縮放,整個裝到裝置中。這種适配方案對開發來說是最為友好的,拿到設計圖即可,不需要跟設計有過多的溝通,設計也不需要出多套圖,降低了成本。

把設計圖想象成一張300X300的圖檔,分别按照寬度等比的裝到150X300、300X300,600X300的裝置中,那麼圖檔的大小将分别變成150X150(沒裝滿容器,可能要增加點純色背景),300X300(剛好),600X600(比容器高了,得出現滾動條了)

倘若設計圖是640*1136,為了在設計圖上量到多少樣式中就能寫多少,我們有如下代碼

var clientWidth = document.documentElement.clientWidth,
    viewport = document.querySelector('meta[name="viewport"]');
    viewportScale = clientWidth / ;
    viewportWidth = ;
    viewport.setAttribute('content', 'width=' + viewportWidth + ', initial-scale=' + viewportScale + ', maximum-scale=' + viewportScale + ', user-scalable=0');
    }複制代碼
           

當然問題也比較明顯:

  • 上面提到的兩個靈異現象,畫不了細線和1px的線在不同位置粗細不一緻,都會存在。進化的方案,将viewport設定為實體分辨率,同時為了在設計圖上量到多少樣式寫多少,可能需要在打包腳本上做一些預處理(無論是百分比還是rem的方式)
  • 生硬的按照設計圖進行等比适配,字型的大小等看起來并不是很舒适。因為css中的1px應該代表多少個實體像素,硬體廠商肯定有過細緻的考慮的,而我們現在修改了這個數值。成本高一點的方案:文字流式、控件彈性、圖檔等比縮放,需要的時候,設計出多套圖,需要開發跟設計有足夠的溝通,media query也要廣泛使用
  • 在不同寬高比的裝置上,顯示效果不盡如人意。頁面底部的一個按鈕,在高屏(指的是相對于寬來說比例高)中顯示靠上;在矮屏(指相對于寬來說比例矮)中顯示靠下,甚至需要滾動一下螢幕才能看見,這個使用者體驗非常不好,更别說極端情況下不允許出現縱向滾動條了。在這種情況下可能要使用一下media query

期待您的關注~~