移動端web app自適應布局探索與總結


移動端web app自適應布局探索與總結

1、困擾多時的問題

在這之前做web app開發的的時候,在自適應方面一般都是寬度通過百分比,高度以iPhone6跟iPhone5之間的一個平衡值寫死,我們的設計稿都是iPhone5的640 * 1136標准,所以高度一般取個大概值,各種圖標的寬高也是取平衡值寫死,然后部分樣式通過媒體查詢來設置,例如背景圖的多倍圖、基礎字體大小、圖標寬高。

這樣做的弊端很明顯:

1. 做出來的頁面在各種手機端看起來的物理大小(高度)是一樣的,所以在大屏手機會覺得頁面稍小,小屏手機頁面稍大

2. 如果要使高度能更好的適應各種手機屏幕,需要寫太多的媒體查詢樣式,效率低下

3. 全屏背景圖片跟頁面元素需要耦合時,元素位置的確定尤為困難(可能需要通過百分比去確定元素的橫向位置,但始終會有誤差)

4. ...

最近在微博上看到流雲諸葛總結的一篇文章《從網易與淘寶的font-size思考前端設計稿與工作流》,其中介紹到的幾種web app適配方案,我們現在的做法恰好是跟拉勾網類似的簡單方案,當然就會有上面我提到的一些問題,最后經過預研和demo測試,我們采取了網易跟淘寶的方案,其實這兩者的方案是大同小異,都是基於rem的適配方案。

2、解決問題的方案

網易跟淘寶的方案介紹在上面流雲諸葛的文章中已經寫的很清楚了,建議可以先看看那篇文章再閱讀下面我所說的,可能會更加清晰。

(1)方案的簡單介紹: 基於rem

前提:頁面元素的布局尺寸全都以設計稿為基准等比例設置。

給html根節點設置一個基礎font-size值,然后頁面的所有元素布局均相對於該font-size值采用rem單位設定。那么基礎的font-size值該如何取呢?

假如通過媒體查詢設置font-size,只能解決一部分的情況,而且並不能完成適配,因為手機屏幕寬度類型實在太多了,所以font-size的取值要通過js計算,取當前viewport的deviceWidth與設計稿的寬的比例值,例如:我們的設計稿尺寸都是640px的,iphone5的deviceWidth是320px,那么計算出來的font-size值就是 320 / 640 = 0.5,因為得出的font-size太小,不方便計算,且有的瀏覽器可能不兼容太小字號,所以將font-size放大100倍,所以最終計算出來的font-size為 320 / 640 * 100 = 50(px); 當然,這個值是根據設計稿來計算的,所以根據計算規則,下面列出幾種常見設計稿相應的font-size值:

1
2
3
4
deviceWidth = 320,font-size = 320 / 6.4 = 50px 
deviceWidth = 375,font-size = 375 / 6.4 = 58.59375px 
deviceWidth = 414,font-size = 414 / 6.4 = 64.6875px 
deviceWidth = 500,font-size = 500 / 6.4 = 78.125px

可在script標簽加上如下代碼:

1
2
3
4
5
6
7
8
9
10
( function  () {
     document.addEventListener( 'DOMContentLoaded' function  () {
         var  html = document.documentElement;
         var  windowWidth = html.clientWidth;
         html.style.fontSize = windowWidth / 6.4 +  'px' ;
         // 等價於html.style.fontSize = windowWidth / 640 * 100 + 'px';    
     },  false );
     })();
         // 這個6.4就是根據設計稿的橫向寬度來確定的,假如你的設計稿是750
         // 那么 html.style.fontSize = windowWidth / 7.5 + 'px';

至此,font-size的基礎值就確定好了,而且知道該font-size值是手機deviceWidth跟設計稿的比例值 的 100倍(重要)

(2)那么頁面元素該如何設置寬高、邊距…

例如:一個設計稿寬高為140px的圖標,左邊距為50px,那么它的css應該這樣寫:

1
2
3
4
5
. icon  {
     width 1.4 rem;  /* 像素換算rem:140px / 100 = 1.4rem */
     height 1.4 rem;
     margin 0  0  0  . 5 rem;
}

因為html的font-size是放大了100倍,所以計算rem時,要用設計稿的實際像素除以100,140px / 100 = 1.4rem; 最后實際的像素大小就會由deviceWidth跟設計稿的橫向寬的比例自動計算出來。

如圖iPhone5下面的效果:

ipone6的效果:

<img%20src= 20title="移動端web%20app%20自適應布局" 20alt="移動端web%20app%20自適應布局">

移動端開發

可以看出來:html的font-size動態根據deviceWidth改變,圖標的寬高、邊距等也根據font-size動態按比例變化,大功告成了?不對,相信機智的你已經看到貌似在iPhone6的下有的圖標背景錯位了。。是的,這暴露出了一個背景使用雪碧圖的一個弊端(由於font-size小數點太多,計算出實際背景圖大小background-size跟背景圖位置background-position時瀏覽器精度不夠可能就會出現位置的偏差(我猜的),這個后面還會詳細講解決方案)

到這里,設置寬高、邊距等都OK了,接下來…

(3)其他元素的字體大小該如何設置?

在流雲諸葛的文章中講到,網易跟淘寶的做法都是使用額外的媒體查詢設置幾種字體大小,例如:

1
2
3
4
5
6
7
8
9
10
11
12
@media  screen  and ( max-width 320px ) {     
     body{ font-size 14px ;} 
}
@media  screen  and ( min-width 321px ) and ( max-width 413px ) {
     body{ font-size 16px ;} 
@media  screen  and ( min-width 414px ) and ( max-width 639px ) { 
     body{ font-size 17px ;} 
@media  screen  and ( min-width 640px ) {
     body{ font-size 18px ;} 
}

<pre%20class="brush:css;toolbar:false">

可為什么不用rem呢?后來去查了一番資料,發現有一種叫做點陣字體的存在(        <a%20href= url="rQT_XFa-uljagexQeYaLvIV8l31ddvIRk8swF5HfBKbbL6nqbbnbS1Qz4Q5dLT2EPYdKdJqGyv1LhFLuFnnP8K"">            什么是點陣字體),也叫作位圖字體,位圖我們都知道,跟矢量圖是有區別的,就是放大會模糊,所以點陣字體也是放大會模糊的,如果根據rem設置字體大小,字體會自由縮放,可能就會導致點陣字體模糊,所以需要設定使用幾種固定大小的字體。不過,在正常情況下,系統自帶的字體都是矢量字體,所以使用rem為單位是沒有問題的,除非你的網頁需要用到特殊的點陣字體。        

總結:如果網頁沒有用到特殊的點陣字體,字體單位使用rem,如果用到了點陣字體,字體需要通過媒體查詢設置幾種固定大小的字體

(4)關於背景圖片的錯位問題

上面已經發現了,通過換算rem設置background-size跟background-position的時候,在一些手機型號下會出現背景圖錯位的情況,可是如果不用rem設置的話,又不能達到適配的目的。(background-size、background-position的rem換算方法跟前面講的寬高設定一樣,都是設計稿尺寸(這時應該是雪碧圖的原始尺寸)除以100倍)

最后經過嘗試,得出了幾種解決方案:

1、如圖(推薦方案):

移動端web app自適應布局探索與總結圖標的樣式:

1
2
3
4
5
6
7
8
9
10
. icon 
     width 1.4 rem; 
     height 1.4 rem;     
     background-image url (sprite.png);     
     background-repeat no-repeat ;     
     background- size 1.4 rem;
.icon 3  {     
     background-position 0  -2.8 rem; 
}

<pre%20class="brush:css;toolbar:false">

解決方法,如圖:

           <img%20src= 20title="移動端開發" 20alt="移動端開發">

移動端web app自適應布局探索與總結代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.icon-fix {
     background none ;
     position relative ;
     overflow hidden ;
}
.icon-fix:after {
     content '' ;
     display block ;
     width 10000% ;
     height 10000% ;
     position absolute ;
     left 0 ;
     top 0 ;
     background-image url (sprite.png);
     background-repeat no-repeat ;
     background- size 140 rem;
     -webkit-transform-origin:  0  0 ;
     -webkit-transform: scale(. 01 );
     transform-origin:  0  0 ;
     transform: scale(. 01 );
}
.icon 3: after {
     background-position 0  -280 rem;
}

<pre%20class="brush:css;toolbar:false">

所有相關代碼 傳送門

2、不使用雪碧圖,使用單個背景圖,這個時候就不存在background-position的需要,只需設定background-size: contain;即可,這樣做的弊端就在於無法使用雪碧圖,圖片請求增多,適用於頁面圖標較少的情況。

3、使用嵌套img標簽,通過絕對定位模擬background-position,具體請看 responsive-sprites,這種做法需要更多的標簽,且img圖片只能放圖標尺寸大小一樣的雪碧圖,而且不能通過媒體查詢使用多倍圖。

以上3中解決方案第一種最優,當然有些特殊情況可能需要按需選擇!

3、寫在最后

關於web app的探索之路還很長,以上純粹個人在學習過程的一些探索和研究,肯定會有不足和錯漏的地方,只有在不斷的實踐中去修正。如果大家發現其中有錯或不好的地方,歡迎提出共同研究,也歡迎大家有更好的方案可以跟我分享研究!

感謝你的閱讀!

 

轉載請注明:HelloWeb-前端網 » 移動端web app自適應布局探索與總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM