基本一直都在作移動端的開發,rem佈局也寫了好久,不過對於實現的原理有些模棱兩可的盲點,本身總結一下留着之後回顧。 本文分如下幾個層面,主打用最最通俗的語言來闡述。css
iphone6尺寸是375*667,那給div設置寬度375px後,爲何寬度不是充滿屏幕呢? 代碼以下:(爲了方面看,我全截圖吧)html
這是爲何呢? 來看一下頁面寬度是多少前端
viewport是什麼?翻譯過來就是視窗的意思,只不過在移動端,視窗稍微有點繞。在解釋這個以前,不得不引出幾個詞彙,分別是物理像素(physical pixel),設備獨立像素(density-indenpendent pixel),設備像素比(device pixel ratio),要怎麼通俗理解這三個詞呢? 容我找找網上的圖。ios
手機屏幕顯示圖像的最小單元。上圖中iphone4和3gs,一樣大小尺寸狀況下,iphone4明顯畫面細膩不少,這是爲何?屏幕尺寸沒變,分辨率提高,畫面就細膩了,更通俗一點的就是iphone4用來顯示圖像的點更多了,把屏幕上的物理像素點想象成整齊排列的點陣,3gs有320 * 480個點而ip4有960 * 640個點。瀏覽器
若是把物理像素看作是負責顯示圖像的硬件的話,那麼設備獨立像素是什麼呢?咱們平時寫的css像素就是設備獨立像素的一種了。而這1px的css像素,在不一樣的手機倒是呈現不一樣的,爲何ip4畫面細膩?就是人家用4個物理像素點來描繪一個css像素。iphone
也就是常說的dpr , dpr = 物理像素/設備獨立像素(注意,是在某一方向的,x軸或者y軸) , 理解這個很重要,iphone6的dpr是2,iphonex的dpr是3。ide
dpr是2的狀況下css畫一個點,這個點是由4個物理像素點提供支撐的。畫一條線的話,那這條線實際上是2排物理像素點支撐的。佈局
同理,dpr是3的狀況下css畫一個點,這個點是由9個物理像素點提供支撐的。畫一條線的話,那這條線實際上是3排物理像素點支撐的。字體
在移動端,視窗分爲三種,分別爲layoutviewport、visualviewport、idealviewport。能夠先記住一個,idealviewport就認爲是設備寬度就好,iphone6就是375,iphone6p 就是414 ,其他兩個先看我下面例子吧。flex
window.devicePixelRatio : 查看設備dpr
document.documentElement.clientWidth : 查看layoutviewport寬度
window.visualViewport.width : 查看visualViewport寬度
window.innerWidth : 查看文檔寬度
須要來個小結了:
默認是980 (針對ios)
設置縮放爲1 寬度爲設備寬度時:就是375(設備寬度)
設置縮放爲2 寬度爲設備寬度時:仍是375(設備寬度)
設置縮放爲0.5 寬度爲設備寬度時:是750(設備寬度的2倍)
layoutviewport 取設置的寬度或者visualviewport他們中的最大值
默認是980 (針對ios)
設置縮放爲1 寬度爲設備寬度時:就是375(設備寬度)
設置縮放爲2 寬度爲設備寬度時:是187.5(設備寬度一半)
設置縮放爲0.5 寬度爲設備寬度時:是750(設備寬度的2倍)
實際上是有公式的,visualviewport = 設備寬度/縮放。也就是visualviewport = idealviewport / initial-scale
顧名思義,是理想視窗意思,就是指的設備尺寸,主要用來和initial-scale配合,計算也就是visualviewport用的。
其實也是能夠從名字就看出來的,layoutviewport佈局視窗,visualviewport視覺視窗。 這裏加個圖,initial-scale = 1 width=devide-width,而後box寬度設置750px,發現html寬度在375,頁面出現滾動條,而且,有意思的是,是按照375寬度排列的,只有那個設置了寬度是750的box寬度變大,因此layoutviewport負責佈局,visualviewport負責視覺,是否是有了點直觀印象了,以下圖:
這裏就更很差用語言描述了,有些抽象。回顧上文,知道iphone3gs iphone6 iphonex三者屏幕尺寸大小不一樣,dpr的話,前二者是1 2 而 iphonex是3。那如何使得一張前端頁面,在每一個手機看起來都是同樣大呢?以iphone6和iphonex來舉例,雖然屏幕寬度都是375,可是iphonex卻擁有更加密集的物理像素點陣。iphone3gs更不用說,320的寬度,dpr又是1。 假若咱們規定,只用設備的物理像素,來繪製css的像素,要求一比一的繪製,那一張320px寬度的頁面,在3個手機上的展現必定大體以下:
這只是一個示意圖,也許並不精準。不過大致就是這樣的,ip6寬度有着750個物理像素點,iphonex寬度有1125個物理像素點,因此根據上面的假想要求,畫出來的必定是這樣的。那麼想要iphone6畫出的這個320px的頁面也充滿屏幕的話,要怎麼作?首先假如設置initial-scale=1, width=device-width,這種狀況下,寬度375的iphone6畫出寬度320px的前端頁面大體什麼樣呢?
rem是什麼,這個你們應該都清楚了。就是給html設置字體大小,假如是30px,那麼頁面中寫了2rem那就是60px。 設計給出一張設計稿,頁面寬度是750px,其中一個div標註了是寬度375px。如何作到在iphone6和iphonex中,看到的這個div都是屏幕寬度的一半呢?
相信你們都已經有答案了。
對於iphone6 設置initial-scale=0.5, width=device-width,而後就直接寫375px就好 對於iphonex 設置initial-scale=1/3, width=device-width,而後就直接寫(375*(3/2))px就好。 缺點就是須要咱們自行計算。
rem方案 : 設計稿750px,div標註375px,對於iphone6 設置initial-scale=0.5, width=device-width,若是html設置font-size爲75px,那div咱們就直接寫5rem就好了。而後適配到iphonex中時,不須要改變div的5rem,只需改變在iphonex中html的字體以及頁面縮放,設置 iphonex中 initial-scale=1/3, width=device-width,而後設置html字體爲112.5px,此時的5rem爲562.5px,恰好是屏幕1125的一半。
上面關於rem適配已經思路實現,如今還差幾個環節,就是爲何設置iphone6是0.5縮放,iphonex是1/3縮放呢?而後又根據什麼設置的html字體?
答: dpr 。那麼又是怎麼設置的?flexible.js就要登場了,flexible.js是手淘的前移動端適配解決方案,爲何是前方案,由於目前瀏覽器對於vw vh支持的更加友好,這個後面再說。看看flexible.js作了什麼吧,直接截圖一些代碼吧。
感受沒什麼好解釋的,就是獲取設備dpr,而後肯定scale嘛
而後把meta標籤塞到html中
不過rem咱們本身來計算的話就很繁瑣了,如給的iphone6,寬度750的設計稿,標註的375px,咱們就寫375px就好,固然是寫成px2rem(375)這樣。
關於flexible.js的實現原理,我也就是挑重點的說了說,仍是建議你們去看大漠老師寫的源碼,一百多行代碼而已,挺好的,也很容易看懂,不過要想清楚爲何要那麼作,就是我上面大篇幅寫的東東啦~
關於vw vh實際上是將視口寬度 window.innerWidth 和視口高度 window.innerHeight 等分爲 100 份,而且此時的視窗並不會隨着 viewport 的不一樣設置而改變。
vw : 1vw 爲視口寬度的 1%
vh : 1vh 爲視口高度的 1%
上面說的設計稿爲 750px,那麼 1vw = 7.5px,100vw = 750px。此時給的不是750設計稿也沒所謂,假如給1000px的設計稿,那咱們寫的1v我就是10px。其實這不就是rem作的事嗎?只不過咱們用rem+flexible.js繞了一圈的感受
做爲後面要補充的點吧,vw等我項目具體實操一波,再來補這個