移動端開發自適應解決方案

原文章地址:點擊打開鏈接

    

移動端自適應方案有很多種
1.流式佈局


也就是固定高度,寬度使用百分比的方法,這種方法會導致一些元素在大屏手機上拉伸嚴重的情況,影響視覺效果,只有在很少一部分手機上能完美的展示設計師想要的效果。攜程之前用的就是流式佈局,但之後也改版了。
2.固定寬度做法


比如早期的淘寶webpage,頁面設置成320的寬度,超出部分留白,在大屏幕手機上,就會出現兩條大百邊,分辨率高的手機,頁面看起來就會特別小,按鈕,文字也很小,之後淘寶改了佈局方案,也就是接下來要講的rem佈局,

3.響應式做法

用一些css框架,比如bootstrap,或者jqueryUI,使用媒體查詢,這種方式維護成本高,很少有大型網站使用這種佈局(據說的)

4.設置viewport進行縮放

天貓的web app的首頁就是採用這種方式去做的,以320寬度爲基準,進行縮放,最大縮放爲320*1.3 = 416,基本縮放到416都就可以兼容iphone6 plus的屏幕了,這個方法簡單粗暴,又高效。說實話我覺得他和用接下去我們要講的rem都非常高效,不過有部分同學使用過程中反應縮放會導致有些頁面元素會糊的情況。

5.rem佈局

rem是css3新引入的單位,在pc端會有兼容性的問題,對移動端比較友好。簡而言之就是通過動態設置html根元素的fontsize,等比縮放元素大小來自適應移動設備。

翻了很多資料,po也測試過最好用省事的就是rem佈局 ,rem佈局也有新舊版,這裏講最普用的阿里團隊的高清方案,也是現在淘寶m端使用的解決方案。
以下是核心js代碼

! function(e) {
    function t(a) {
        if (i[a]) return i[a].exports;
        var n = i[a] = {
            exports: {},
            id: a,
            loaded: !1
        };
        return e[a].call(n.exports, n, n.exports, t), n.loaded = !0, n.exports
    }
    var i = {};
    return t.m = e, t.c = i, t.p = "", t(0)
}([function(e, t) {
    "use strict";
    Object.defineProperty(t, "__esModule", {
        value: !0
    });
    var i = window;
    t["default"] = i.flex = function(e, t) {
        var a = e || 100,
            n = t || 1,
            r = i.document,
            o = navigator.userAgent,
            d = o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),
            l = o.match(/U3\/((\d+|\.){5,})/i),
            c = l && parseInt(l[1].split(".").join(""), 10) >= 80,
            p = navigator.appVersion.match(/(iphone|ipad|ipod)/gi),
            s = i.devicePixelRatio || 1;
        p || d && d[1] > 534 || c || (s = 1);
        var u = 1 / s,
            m = r.querySelector('meta[name="viewport"]');
        m || (m = r.createElement("meta"), m.setAttribute("name", "viewport"), r.head.appendChild(m)), m.setAttribute("content", "width=device-width,user-scalable=no,initial-scale=" + u + ",maximum-scale=" + u + ",minimum-scale=" + u), r.documentElement.style.fontSize = a / 2 * s * n + "px"
    }, e.exports = t["default"]
}]);
flex(100, 1); 

代碼原理:

1.根據設備屏幕的DPR(設備像素比,比如dpr=2時,表示1個CSS像素由2X2個物理像素點組成) 動態設置 html 的font-size
2.同時根據設備DPR調整頁面的縮放值,進而達到高清效果。

方案優勢:

1.引用簡單,佈局簡便(只要把js代碼貼到head標籤裏面,就可以使用了,設計稿一般是640 或者750的,不需要進行單位換算,直接用設計稿的尺寸就可以,比如設計稿上有一個btn的高度爲80px,寬度爲120px,高清方案默認1rem=100px,那麼 btn的寬度就設置爲:)

.btn {
    width:0.8rem
    height:1.2rem
}

2.根據設備屏幕的DPR,自動設置最合適的高清縮放。保證了不同設備下視覺體驗的一致性。
舊方案,屏幕越大,元素也越大,新方案,屏幕越大,看到的越多
看得越多的理解:
比如,一篇很長的文章在ip4上,一屏盛不了那麼多內容,而在ip6plus上,可以全部看清楚,這是因爲,新方案會根據dpr來縮放視口,大屏小屏的手機上,顯示的字體大小都是一致的,當然在大屏上看到的東西就多咯~
3.有效解決移動端真實1px問題(這裏的1px 是設備屏幕上的物理像素)

注意

並不是所有用px的地方都要用rem,rem佈局只針對固定寬度。

依需求而定,比如淘寶頁面底下的tabar,和頭部搜索區域,都是用百分比來佈局的,或者flex和模型,當在ipad上打開的時候就可以看見,頭部和tab是撐滿全屏的。
中間的主要內容(最外部的容器)要設置一個max-width,demo設置的是max-width:10rem,這裏我不太明白爲什麼要設置成10rem,有弄明白的小夥伴希望能告訴我。謝謝(已解決,和設置最外層寬度爲100%是一樣的道理,10rem 可以適配到所有手機設備。1000%可以適配ipad,demo試試就知道了)
(應用了此方案,不管設計圖多寬(當然,一般寬度爲750,640也可以),最外層的div寬度設爲100%就行,然後就可以愉快的佈局了,不會出現你說的白邊的情況。)

對於尺寸比較大的元素,應該考慮用百分比。rem做單位的元素在哪種設備下都是固定大小,這點必須牢記!!

可能遇到的問題

1.問:爲啥手機網頁效果圖寬度是要640或者750的,我非得弄個666的不行咩?

答:老實說當然可以,不過爲了規範,640或者750是相對合適的。拿Iphone 5s 舉例,它的css像素寬度是320px,由於它的dpr=2,所以它的物理像素寬度爲320 × 2 = 640px,這也就是爲什麼,你在5s上截了一張圖,在電腦上打開,它的原始寬度是640px的原因。那 iphone 6 的截圖寬度呢? 375 × 2 = 750那 iphone 6 sp 的截圖寬度呢? 414 × 3 = 1242以此類推,你現在能明白效果圖爲什麼一般是 640 ,750 甚至是 1242 的原因了麼?(真沒有歧視安卓機的意思。。。)

2.問:寬度用rem寫的情況下, 在 iphone6 上沒問題, 在 iphone5上會有橫向滾動條,何解?

答:假設你的效果圖寬度是750,在這個效果圖上可能有一個寬度爲7rem(高清方案默認 1rem = 100px)的元素。我們知道,高清方案的特點就是幾乎完美還原效果圖,也就是說,你寫了一個寬度爲 7rem 的元素,那麼在目前主流移動設備上都是7rem。然而,iphone 5 的寬度爲640,也就是6.4rem。於是橫向滾動條不可避免的出現了。怎麼辦呢? 這是我目前推薦的比較安全的方式:如果元素的寬度超過效果圖寬度的一半(效果圖寬爲640或750),果斷使用百分比寬度,或者flex佈局。就像把等屏寬的圖片寬度設爲100%一樣。

3.問:不是 1rem = 100px嗎,爲什麼我的代碼寫了一個寬度爲3rem的元素,在電腦端的谷歌瀏覽器上寬度只有150px?

答:先說高清方案代碼,再次強調咱們的高清方案代碼是根據設備的dpr動態設置html 的 font-size,如果dpr=1(如電腦端),則html的font-size爲50px,此時 1rem = 50px如果dpr=2(如iphone 5 和 6),則html的font-size爲100px,此時 1rem = 100px如果dpr=3(如iphone 6 sp),則html的font-size爲150px,此時 1rem = 150px如果dpr爲其他值,即便不是整數,如3.4 , 也是一樣直接將dpr 乘以 50 。
再來說說效果圖,一般來講,我們的效果圖寬度要麼是640,要麼是750,無論哪一個,它們對應設備的dpr=2,此時,1 rem = 50 × 2 = 100px。這也就是爲什麼高清方案默認1rem = 100px。而將1rem默認100px也是好處多多,可以幫你快速換算單位,比如在750寬度下的效果圖,某元素寬度爲53px,那麼css寬度直接設爲53/100=0.53rem了。
然而極少情況下,有設計師將效果圖寬定爲1242px,因爲他手裏只有一個iphone 6 sp (dpr = 3),設計完效果圖剛好可以在他的iphone 6 sp裏查看調整。一切完畢之後,他將這個效果圖交給你來切圖。由於這個效果圖對應設備的dpr=3,也就是1rem = 50 × 3 = 150px。所以如果你量取了一個寬度爲90px的元素,它的css寬度應該爲 90/150=0.6rem。由於咱們的高清方案默認1rem=100px,爲了還原效果圖,你需要這樣換算。當然,一個技巧就是你可以直接修改咱們的高清方案的默認設置。在代碼的最後 你會看到 flex(100, 1) ,將其修改成flex(66.66667, 1)(感謝簡友:V旅行指出此處錯誤! 2017/3/24)就不用那麼麻煩的換算了,此時那個90px的直接寫成0.9rem就可以了。

4.問:高清方案在微信上,有時候字體會不受控制變的很大,怎麼辦?

答:點我,這是我對該問題的總結
5.問:我在底部導航用的flex感覺更合適一些,請問這樣子混着用可以嗎?

答:咱們的rem適合寫固定尺寸。其餘的根據需要換成flex或者百分比。源碼示例中就有這三種的綜合運用。
6.問:在高清方案下,一個標準的,較爲理想的寬度爲640的頁面效果圖應該是怎樣的?

7.這個會和bootstrap衝突。
解決辦法:
1,將bootstrap 中,凡是用到px的單位一律換成rem
2,如果你有使用webpack,建議使用將css轉成rem的包(postcss-pxtorem)將自動完成第一步的操作。

8.@2x和@3x的圖片還要判斷不同的dpr下用不同的圖片。

Normalize.css 是一個可以定製的CSS文件,它讓不同的瀏覽器在渲染網頁元素的時候形式更統一。

Normalize.css 能幹什麼:

保留有用的默認值,不同於許多 CSS 的重置

標準化的樣式,適用範圍廣的元素。

糾正錯誤和常見的瀏覽器的不一致性。

一些細微的改進,提高了易用性。

使用詳細的註釋來解釋代碼。

支持的瀏覽器:

Google Chrome (latest)

Mozilla Firefox (latest)

Mozilla Firefox ESR

Opera (latest)

Apple Safari 6+

Internet Explorer 8+

點擊瀏覽:一個標準的640手機頁面設計稿參考(沒錯,在此方案中,你可以完全按照這張設計稿的尺寸寫佈局了。就是這麼簡單!)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章