Web移動端適配總結

comWang發表於2018-11-14

一. 1px邊框問題

想必各位無論在面試中,還是工作中,應該遇到過1px邊框的問題。不知道也沒關係,現在我們就來複習一下(知道的朋友可以跳過去看第二部分了)。 1px邊框,顧名思義就是前端畫出1px的線,這裡的1px,指的是螢幕1px大小。那麼螢幕的1px和css中的1px有什麼區別呢?每個物理畫素(也就是螢幕的1px)是 影象顯示的最小單元,css的1px是瀏覽器渲染的基本單位,在普通螢幕下,1px對應1物理畫素,在2倍屏、3倍屏下1px分別對應2物理畫素、3物理畫素。這就好比實驗用的 座標紙,假如紙上有10小格(相當於10個物理畫素),作圖時把你自己座標系的一個單位用1小格表示,那麼你最終做的圖佔整個座標紙的面積就比較小, 把座標系的一個單位用10小格表示,可能整個座標紙只能畫出一部分影象,但會保留更多細節。在第2種情況下,同一單位長度的線會是第1種情況下的10倍長。瀏覽器在高倍屏下 渲染也是如此,在2倍屏下畫的是2倍粗的線,3倍屏下畫的是3倍粗的線。

二. 不同尺寸的螢幕適配

移動端的螢幕適配,不僅僅需要考慮各種尺寸,還要考慮dpr(螢幕畫素比,可以理解為每px用多少物理畫素顯示),dpr = 2就是2倍屏。同樣是寬為350px的裝置,普通屏看起來正常,2倍屏看起來線條就很 粗,你可能用一些hack例如transform縮放、製造陰影模擬邊框,這些多少存在一些問題,如果需要全域性都能畫出1px的線呢?我們只要保證讓1px始終只佔1個物理畫素就行了。這裡使用meta標籤的viewport對全域性檢視進行縮放。 一般是下面這個樣子:

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
複製程式碼

對於2倍屏設定initial-scale=0.5,對於3倍屏設定initial-scale=0.33,因此,我們還需要在網頁渲染前用指令碼通過window.devicePixelRatio獲取dpr,然後將initial-scale設定為 1/dpr。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" language="zh-cn-hans">
        <script>
            (function(){
                function resetViewPort (){
                    var viewport = document.querySelector('meta[name = viewport]');
                    if(!viewport){
                        viewport = document.createElement("meta");
                        var head = document.querySelector("head");
                        head.insertBefore(viewport,head.firstChild);
                    }
                    var ratio = window.devicePixelRatio||1;
                    var content = 'width=device-width,initial-scale='+ Math.round(100/ratio) / 100 +',maximum-scale=1,user-scalable=no';
                    viewport.setAttribute("content",content);
                };
                window.addEventListener('DOMContentLoaded',resetViewPort);
            })()
        </script>
    </head>
    <body>
    </body>
</html>
複製程式碼

至此,所有螢幕下1px都對應1物理畫素了,現在我們只需要考慮不同的螢幕尺寸。不過現在問題來了,因為px的長度已經和之前不一樣了,如果現在還用px描述元素,肯定會變小,因此我們需要 用另一種單位來表示元素。現在讓我們想想css除了px外還有那些單位?

  • %

  • em,rem

  • vw

  • ...

%一般是相對於父級元素,當有多級巢狀時,就很複雜,不好確定了,同理,em也有這個缺點。再來看rem,它總是相對於根元素的font-size,根元素是唯一的,只要我們保證不同螢幕下根 元素的font-size與螢幕的寬度比例一致,就能得到一樣的顯示效果。這是個很好的方法,只需要在上面的指令碼加幾行程式碼就行了,瀏覽器相容性也很好,很多文章也介紹了這種方案。不過今天,他不是我們的主角。再來看看vw,1vw表示的是1/100的螢幕寬度,一個寬為30vw的元素在A裝置佔螢幕寬度的30%,在B裝置同樣佔螢幕寬度的30%,這不就是我們想要的嗎?讓我們來看看vw的 相容性,可以看出vw幾乎完全相容。實際上font-size + rem就是模擬的vw,為何我們不直接用它呢?

三. 自動轉換外掛

我們一般是拿著設計稿,根據標註寫尺寸。標註一般是px為單位,現在寫成以vw為單位,則需要進行一個轉換。這種換算的工作我們讓外掛來做,不過目前好像沒找到相關postcss外掛,於是自己寫了一個——postcss-unify,程式碼很簡單隻有20行,就是用正則匹配然後替換,感興趣的你也可以自己做一個。這裡簡單說一下postcss,它能將css轉化為js物件便於我們 操作,再將結果轉化成css程式碼,在這裡瞭解更多(寫外掛的方法在連結裡也有)。

四. 其他

雙十一都過了,老子還是單身!
本文參考了很多文章,同時結合了實踐探索,有什麼不對或更好的地方歡迎提出。
~~都被你看個精光了,還不給個贊?

相關文章