移動端開發(fā)自適應解決方案(阿里團隊高清方案)

研究m端開發(fā)自適應有一段時間了,下面做一個總結
移動端自適應方案有很多種
1.流式布局


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


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

3.響應式做法

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

4.設置viewport進行縮放

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

5.rem布局

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

翻了很多資料,po也測試過最好用省事的就是rem布局 ,rem布局也有新舊版,這里講最普用的阿里團隊的高清方案,也是現(xiàn)在淘寶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.根據(jù)設備屏幕的DPR(設備像素比,比如dpr=2時,表示1個CSS像素由2X2個物理像素點組成) 動態(tài)設置 html 的font-size
2.同時根據(jù)設備DPR調整頁面的縮放值,進而達到高清效果。

方案優(yōu)勢:

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

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

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

注意

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

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

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

可能遇到的問題

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

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

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

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

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

答:先說高清方案代碼,再次強調咱們的高清方案代碼是根據(jù)設備的dpr動態(tài)設置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為其他值,即便不是整數(shù),如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)就不用那么麻煩的換算了,此時那個90px的直接寫成0.9rem就可以了。

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

答:參考
5.問:我在底部導航用的flex感覺更合適一些,請問這樣子混著用可以嗎?

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

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

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

Normalize.css 是一個可以定制的CSS文件,它讓不同的瀏覽器在渲染網(wǎng)頁元素的時候形式更統(tǒng)一。

Normalize.css 能干什么:

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

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

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

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

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

支持的瀏覽器:

Google Chrome (latest)

Mozilla Firefox (latest)

Mozilla Firefox ESR

Opera (latest)

Apple Safari 6+

Internet Explorer 8+
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容