兩周前,PO提了個掃描二維碼訪問H5頁面的需求,由于自己一直沒有接觸過移動端,也對這其非常感興趣,所以自告奮勇地接下了這個需求!
不過,接觸了后發現其中的知識點與坑是真的多!
1、必須得知道的名詞
在PC端,我們其實不需要關心那么多,根據UI給的設計稿PSD圖切就好了,量出來多少像素就是多少像素,最多對于寬屏還是窄屏做下處理就好了。但這些在移動端是行不通的!
比如說分辨率,原來在我的理解里,屏寬 * 屏高就是分辨率,這個在原來的PC端也沒什么問題,但是,自從Apple推出了高清屏,也就是Retina屏后,這個理解就有問題了!所以,什么是高清屏?當年喬幫主對Retina得定義是:顯示器像素密度只要超過 xxx ppi就無法區分出單獨的像素。
- PPI(Pixels Per Inch): 每英寸所擁有的像素數目,也叫像素密度
什么?屏幕就這么大,難道像素密度不是固定的嗎?其實,我之前也是這么認為的,然而非也,這也涉及到了幾個概念。
- 物理像素:顯示器上最小的物理顯示單元,在操作系統的調度下,每一個設備像素都有自己的顏色值和亮度值。
- 邏輯像素:也就是我們所說的CSS像素,是一個抽象的單位,用來精確度量頁面上的內容。
- 設備無關像素:是計算機坐標系統中得一個點,這個點代表一個可以由程序使用的虛擬像素(比如: css像素),然后由相關系統轉換為物理像素。
- 設備像素比:物理像素和設備獨立像素的對應關系,其值為在某一方向上 物理像素 / 設備獨立像素。
所以嘛,我們一直所說的像素,其實指的是邏輯像素,但最終我們看到的效果,是由硬件渲染成的一個個物理像素,也就是說我們指定的CSS像素最后需要與物理像素對應起來。
比如我上手的iPhone6,設備獨立像素為375 * 667,devicePixelRatio為2,那么其分辨率就是750 * 1334.如果我指定頁面100%占滿屏幕,就是說1個CSS像素要對應4個物理像素(長寬都是2倍嘛),由于像素作為最小不可分割的單位,所以其余3個像素會就近取色,也就造成了看上去會模糊。(放張網上盜的圖)
現在我們也明白了,移動端為什么會有@2x和@3x之類的圖片了吧,就是為了在不同devicePixelRatio的設備上能夠清晰地顯示!
2、移動端適配
移動端最麻煩應該就是適配問題了,畢竟市面上的各類機型太多了,以Apple家的為例,Android就不提了...
那么多機型,總不能為每個機型都量身定做吧?那么開發成本太高了!目前流行的做法是UI給出針對某一機型的設計稿,比如iPhone6的750 * 1334,前端對每個機型做適配。
那么怎么適配呢?用百分比做單位?可以是可以,但計算比較麻煩,還有像padding之類的百分比是根據父元素的width計算,需要注意!那么沒有更好的辦法了嗎?有的! rem了解一下!
- rem: CSS單位,1rem等于根元素的font-size大小(HTML元素)
那么我們根據頁面的大小,動態計算HTML元素的font-size不就行了?對的!但前提我們得設置viewport,也就是視口。那么視口又是什么呢?
- viewport: 指的是瀏覽器上顯示網頁內容的區域。
其實viewport我們一直都在使用,只是沒注意到而已。我們知道一個塊元素不設width情況下,會繼承自其父元素的width,若父元素也沒有設置,則再向上繼承,如此,一直到body元素繼承自html元素。那么html元素的width繼承自誰呢?答案就是viewport!
在移動端,viewport的大小其實并不等于瀏覽器的可視區域,為什么呢?因為移動端瀏覽器也想顯示PC端的網頁,所以會將默認的viewport的width設置為980px或者1024px,然后再根據自身的屏幕進行縮小。不這么做的話,移動設備再寬也比不上PC,所以viewport要是等于移動端瀏覽器的可視區域的話,網頁的布局一定會亂掉!
ppk大神將viewport分成了layout viewport、visual viewport、idea viewport。有興趣的可以看看這篇博客。https://www.cnblogs.com/2050/p/3877280.html
因此,在移動端,我們首先得要在head中添加一行meta標簽,重新設置viewport。
<meta name="viewport" content="width=device-width, initial-sacle=1.0">
以上代碼的意思是,將viewport的width設置為設備可視區域的width,并設置初始縮放值為1.0,也就是不縮放。
還可以設置其它的參數:
- maximum-scale:允許用戶縮放到的最大比例。
- minimum-scale:允許用戶縮放到的最小比例。
- user-scalable:用戶是否可以手動縮放。