多的話就不說了,反正WebApp現在是很火,PC端網頁已經遠遠不能滿足大家的胃口,今天來談談如何制作一個WebApp(也可稱之為自適應Web)。
現在一般有兩種方式:
當然我們開頭的meta標簽是不能少的。
<metaname="viewport"content="width=device-width, initial-scale=1.0"/>
1.采用CSS3的@media媒體查詢(這種方式較簡單粗暴,也就是傳說的流式布局)
要點
(1)寬度都用百分比來設置
(2)對要自適應的Div設置float屬性(其實原理就是利用float屬性當寬度不夠而換行的特性)
(3)用@media查詢對不同屏幕尺寸設置樣式
下面貼出自己做的一個小demo:
效果:
Iphone5下:
Ipad下:
這樣就實現了簡單的自適應,但是這樣做有很大的缺陷:
(1).在大屏手機會覺得頁面稍小,小屏手機頁面稍大
(2).如果做復雜一點的頁面@media查詢會非常的多
(3).Dom上的元素如果要和背景圖片結合位置不好確定。
下面就是第二種,現如今最火的一種做法:
基于Rem的適配方法,動態改變1rem的值(html font-size的值)來達到適配。這種適配方法也有兩種類型,分別以網易和淘寶為例。(其實差別不大)
在非根元素下1rem的值相當于根元素的font-size大小。rem適配的原理是等比縮放!!!一般根據寬度
網易流程如下:
(1)確定基礎稿,假設基礎稿寬度為640px。
(2)在640px的基礎稿下,假設一個按鈕的寬度為150px,剛才我們說了,rem適配的原理是等比縮放。那么怎么去等比,我們就借助rem這個媒介,我們還提到一般是根據寬度去做縮放,那么我們把rem的計算和寬度建立上聯系不就行了?網易的做法是在計算1rem值的時候根據屏幕寬度比來計算。
(3)?我們設置在640px的基礎稿下1rem = 100px。那么這個按鈕的寬度就應該為1.5rem(為什么設置100?其實任何值都行,只是100方便與與計算)。
(4)那么這個視覺稿做成的網頁在其他屏幕上怎么去適配呢?我們不知道其他屏幕到底多大呀~這就是我們設置基礎稿的原因。再一次強調rem的原理是等比縮放。那么在640的屏幕下1.5rem為按鈕的寬度,那么當網頁到了320px的屏幕下呢?根據等比縮放原則=》640/320 = 100 / 當前頁面1rem的值。
代碼實現也就是:
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';
這樣在沒個頁面安裝基準稿等比縮放算出來的1rem的值就能達到頁面的適配
效果圖:
ipad下:
iphone6plus上:
可以看到的是這套方法是完全可行的,我們的根font-size會根據不同的屏幕寬度而實現自適應,淘寶的和這個一個道理我就不再做demo了。
另外個人推薦使用網易的方法,不用去復雜的轉換rem。
淘寶流程如下:
(1)前期步驟和網易一樣都是設置先設置基準稿
(2)淘寶還考慮了dpr的影響,一般基準稿是基于iphone的,而iphone這種retina屏幕的dpr為2
(3)淘寶的做法就是動態的去設置meta來縮放,以達到高清適配的目的
????????????meta.setAttribute('content','initial-scale='+1/dpr +', maximum-scale='+1/dpr +', minimum-scale='+1/dpr +', user-scalable=no');這里對頁面進行了縮放,就會涉及到圖片失幀的問題,所以得用2倍圖3倍圖寫css hack解決,還有一點就是頁面根據dpr做了縮放,所以在計算1rem的值的時候得乘上dpr值
(4)那么這里計算rem與網易的區別就出來了,網易是在計算1rem值的時候根據屏幕寬度比來計算,而淘寶的1rem值都是屏幕寬的10份,它在計算1rem的值的時候其實是將元素寬度和屏幕寬度建立聯系來計算的。所以淘寶的高清適配方案放在網易上也是可行的。
????????????var dpr = window.devicePixelRatio || 1, scale = 1 / dpr;??
? ? ? ? ? ? var docEle = document.documentElement;
????????????var deviceWidth = docEle.clientWidth;
????????????var metaEle = document.querySelector('meta[name="viewport"]');
????????????metaEle.setAttribute('content', 'width=' + dpr * deviceWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
????????????docEle.setAttribute('data-dpr', dpr);? ? ?//css hack
????????????if (deviceWidth > 750) deviceWidth = 750;
????????????document.documentElement.style.fontSize = deviceWidth * dpr / 7.5 + 'px';
(5)接下來就是計算1rem的值,也就是 基準值(1rem=clientwidth*dpr/10。這里說過任何值都行)
(6)之后布局所用到的位置單位全部用Rem代替(這就和網易的不同了。若有一個750px的div,假設我們算出來的1rem的為50,那么該div的寬度就該寫為15rem)轉換公式rem=px/ 基準值,這里如果你自己用這種方法的話會發現當你要將px轉化為rem時,計算會很麻煩,但是前端構建的強大,less,sass能輕松解決。
以上只是樓主的一些個人體會,肯定有很多不足,歡迎批評指正