天天看點

移動端像素與viewport原理

引言

移動端開發時會涉及到viewport的問題,做項目時加個meta标簽就可以了,不過還是需要了解一下原理,不然在1px像素問題上的解決就不能了解

像素

當拿到ued給的移動端稿時,上面寫着86px,如果真把一個div設為height:86px,就會高很多。這就是實體像素dp和像素px的差別,ued給的是實體像素,而我們在css中設定的是邏輯像素,他倆之間有個轉換關系dpr

【像素px】: 邏輯像素,在不同裝置上可大可小,浏覽器使用的抽象機關

【 實體像素dp,pt】: 裝置像素,固定大小

【裝置像素縮放比】dpr:

1px=dpr^2*dp

以iphone5為例子

實體像素640dp * 1136dp (百度一下)

移動端像素與viewport原理

邏輯像素320px * 568px (打開谷歌浏覽器開發者模式手機模式)

移動端像素與viewport原理

dpr=2

1css像素=4裝置像素 (面積上)

在長度上設定時候

1css=2裝置

是以剛才舉的例子,ued給的86像素,我們在css中設定為height:43px即可

ppi: 螢幕每英寸的像素數量
移動端像素與viewport原理

【注意】:算ppi用實體像素算,而不是px

ppi越高,像素數越高,圖檔越清晰

調節pc分辨率的時候,可以發現,分辨率調得越高越清晰,但螢幕上的icon越小

移動端像素與viewport原理

螢幕上的icon越小,也就是系統預設縮放比越大,以下有四種次元的ppi縮放比

移動端像素與viewport原理

之前算過IPhone5的ppi為326,屬于超高清屏,大于320,縮放比為2,dpr=2

理清一下關系

移動端像素與viewport原理

可以看這篇文章 移動裝置分辨率(終于弄懂了為什麼移動端設計稿總是640px和750px)

三個viewport

手機浏覽器預設為我們做兩件事情

  1. 頁面渲染在一個980px的viewport(ios)
  2. 縮放

    如果不用viewport直接縮放,排版就會亂掉,是以為了排版正确,僞造了一個980的布局viewport

    移動端像素與viewport原理
    手機螢幕分為兩層,底層是布局viewport(980px)負責渲染頁面,上層是我們通過縮放控制的視口viewport
  • visual viewport:視口/度量viewport
  • layout viewport:布局viewport
  • 檢視layout viewport: document.body.clientWidth
  • 檢視visual viewport:window.innerWidth

為了驗證,我把我的剛建立的項目中對viewport的meta标簽設定去掉,打開谷歌浏覽器的手機模式,看到的是一個可以在大頁面挪動的手機視窗

移動端像素與viewport原理

右移一下

移動端像素與viewport原理

這就驗證了底層是布局viewport(980px)負責渲染頁面,上層是我們通過縮放控制的視口viewport

如果用980的layout viewport

移動端像素與viewport原理

頁面需要縮放

是以不用預設的980px的布局viewport,會使用meta标簽對其設定

【為什麼不用預設的980px的布局viewport 】

寬度不可控制,不同系統的預設值可能都不同

頁面縮小版顯示,不友好

連結不可點

有縮放,縮放後又有滾動

因為不用980px布局viewport, 是以就需要用到meta标簽來設定布局viewport

移動端像素與viewport原理

以iphone5為例,設定< meta name=‘viewport’ content=“width=320”>

這時候一張320px的圖檔可以填充完螢幕

因為手機各個不同,是以就用

< meta name=‘viewport’ content=“width=device-width”>

那為什麼需要縮放比呢

比如我裡面放一個610px的圖檔,那麼visual viewport為610,layout viewport為320,縮放比不等于1

效果:

移動端像素與viewport原理

可以在console中看出:layout viewport為320,visual viewport為610,此時頁面可向右滑動出剩餘的div,也可以縮放

如果加一個對縮放比的控制,那麼布局變化和視口變化都是320,不可向右滑動

< meta name=‘viewport’ content=“width=device-width, initial-scale=1, user-scalable=no”>

  • 通過width=device-width讓布局viewport=裝置寬度
  • 通過initial-scale=1讓視口viewport=布局viewport