前幾天偶然看到一個pc端網頁,發現用手機打開居然同比縮放了,做爲一個前端從業者,我天然想要弄清它究竟是怎麼縮放的。以後查了它的meta信息,css和js,發現沒有任何兼容手機端的代碼,那它究竟是怎麼縮放的呢?百思不得其解,最後無心中看別人說viewport的默認值是980px,才知道原來是viewport的鍋。css
因而我深刻的複習了一下viewport相關知識,把心得記錄下來,供之後開發時參考,相信對其餘人也有用。html
原本看了移動前端開發之viewport的深刻理解,可是仍然有一些概念不理解,因而去看了PPK大神對於viewport的研究(第一篇,第二篇,第三篇),算是理清了。前端
首先從css像素和實際像素提及,css像素就是咱們寫的css的像素,若是沒有進行任何縮放的話,css像素就和實際像素是同樣的,若是用瀏覽器對頁面進行了縮放,那麼css像素不變,實際像素會根據縮放比例變化。瀏覽器
值得一提的是,縮放是個很重要的概念,在pc端的網頁通常沒有進行縮放,因此1px的css像素經常等於1px的實際像素。ui
viewport寬高是用document.documentElement.clientWidth和document.documentElement.Height來取到的。細心觀察能夠發現,document.documentElement就是html元素,而document.documentElement.clientWidth就是html的寬度。scala
咱們知道,css裏面的包含塊的寬度會自動延伸至父元素的寬度,因此最外層包含塊的寬度會延伸到body的寬度,而body的寬度會延伸到html的寬度,那html的寬度延伸到什麼寬度呢?答案是viewport的寬度!因此能夠用html的寬度來度量viewport的寬度。code
另外,這裏有一個小坑,就是html的寬度是能夠修改的,可是即便修改了html的寬度,document.documentElement.clientWidth和document.documentElement.Height的值仍然是viewport的寬高,這是html元素的這2個屬性的不一樣之處。htm
那當咱們改了html的寬度以後,怎麼得到html的寬高呢?方式是利用document.documentElement.offsetWidth和document.documentElement.offsetHeight.blog
明白了上面viewport的寬高機制以後就很好理解移動端的viewport了。開發
移動端因爲設備的像素很小,因此若是不進行縮放的話,就只能看到pc端網頁的部份內容,因此移動端瀏覽器在兼容的時候,會對頁面進行縮放,可是爲了不在縮放的時候頁面發生重排和重繪,瀏覽器就有2個viewport,一個是咱們常說的viewport,它用來放置頁面,它的默認值寬度是980px;另外一個是可視區域的visual viewport,它是移動端的可視區域,用來放大或縮小。
在pc端,咱們常說的viewport就等於可視區域的visual viewport,因此css像素和實際像素比是1比1。
在移動端,因爲放置頁面的viewport的寬度默認爲980px,可是設備的寬度經常小於980px,因此可視區域的viewport會對它進行縮放,直到頁面內容的寬度正好達到屏幕的寬度。因此咱們用手機端看到的pc端頁面都是已經縮放過的(若是頁面沒有設置viewport的話)。
注意,有些狀況下,可視區域的viewport的寬度不會等於放置頁面的viewport的寬度。好比有一個頁面,咱們設置它的最外層包含塊的最小寬度爲1250px,那麼放置頁面的viewport的寬度還是默認值980px,可是可視區域的viewport的寬度會達到1250px。
那怎麼獲得可視區域的縮放比例呢?它等於設備的寬度除以可視區域的寬度,即:screen.width/window.innerWidth。(注意不是viewport的寬度)
其餘寬度信息也能夠按照上面列出的方法來取。
若是是專門爲移動端作的頁面,那麼經常要設置viewport,使它的兩個viewport都等於設備寬度。代碼以下:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
viewport的其它設置方法能夠參考:移動前端開發之viewport的深刻理解