1. 程式人生 > >移動端頁面適配rem和vw的使用和轉換

移動端頁面適配rem和vw的使用和轉換

物理畫素:dp、比如蘋果7主屏解析度:1334dp*750dp

邏輯畫素:px、開發中用到的畫素

畫素縮放比:dpr、物理畫素跟邏輯畫素之間的比例關係

畫素密度:ppi、螢幕每英寸畫素密度【√(1334^2+750^2) / 4.7 = 325.61228......PPI】


邏輯畫素不會變,但是物理畫素會隨著硬體技術提升變化,比如以前1dp的大小約等於1px的大小,現在1dp僅是1px的四分之一(在同樣大小的螢幕下,dp變小了,說明主屏解析度提高了),這時,1px = 2^2dp,目前ppi最高的手機索尼1px約等於8^2dp

畫素縮放比DPR在手機出廠的時候就已經定了,js中可以通過window.devicePixelRatio

獲取到當前裝置的dpr;

dpr = dp / px

px = dp / dpr

例外:在蘋果6 plus和7 plus的螢幕ppi為401,所以dpr為3,物理畫素為1920dp*1080dp

px 按理說應該是 1080/3 = 360,而實際他預設顯示為414px,因為蘋果6/7plus用了更好的螢幕,但不能讓5.5英寸顯示內容比6/7的4.7英寸顯示內容還少呀,(6/7是375px),所以蘋果就採取了措施,選了以下較為折中的a方案:


設計稿都是採用的物理畫素,一般750dp較多,螢幕X軸為750dp的裝置正常情況下dpr為2,所以750dp的裝置在瀏覽器中顯示的最大寬度為750/2 = 375px,當你在body中給一個width為375px的div時,此時顯示剛好完全100%寬度,換了其他裝置可能就有差距了,所以這裡我們就要考慮到頁面適配

了,在不同手機螢幕尺寸上怎樣讓看上去效果一樣?

vw:相對單位,相對於最大視口寬度,最大視口寬度  = 100vw,所以要設定meta標籤:<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">,讓內容寬度=視口寬度;

由此得出,一個元素寬度的vw = 該元素在設計稿中的寬度 / (設計稿總寬度/100);

rem:相對單位,1rem = html的font-size,會隨著html的font-size改變而改變,html預設font-size是16px,可以將body的font-size還原為16px;

預設html的font-size為16px時rem值對照:

|  px  |     rem    |
------------------------
|  12  | 12/16 = .75   |
|  14  | 14/16 = .875  |
|  16  | 16/16 = 1     |
|  18  | 18/16 = 1.125 |
|  20  | 20/16 = 1.25  |
|  24  | 24/16 = 1.5   |
|  30  | 30/16 = 1.875 |
|  36  | 36/16 = 2.25  |
|  42  | 42/16 = 2.625 |
|  48  | 48/16 = 3     |

例:為了方便計算,假設html的font-size設定為100px,設計稿是750dp(iphone6/7):

視窗寬度rem = 375px / 100px = 3.75rem,

那麼當用戶在不同裝置螢幕上訪問這個頁面呢,例如iphone6/7 plus,會有空白出現,所以要實現適配的話就需要用js程式碼來動態更改html的font-size了,原理就是獲取當前使用者裝置螢幕寬度,因為rem的值是不變的,我們只需要動態來計算html的font-size就行了:

(function (doc, win) {
            var docEl = doc.documentElement,
             // orientationchange 事件 用來監聽手機螢幕的反轉
            resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
            recalc = function () {
              var clientWidth = docEl.clientWidth;//(window.innerWidth);UC 或者QQ 安卓4.0 以下原生瀏覽器下面是沒有
              if (!clientWidth) return;
              
               docEl.style.fontSize = 100 * (clientWidth / 375) + 'px';
            };

            if (!doc.addEventListener) return;
            win.addEventListener(resizeEvt, recalc, false);
            //DOMContentLoaded dom 載入完成,onload 有什麼區別 dom css js OK 才執行的
            doc.addEventListener('DOMContentLoaded', recalc, false);
        })(document, window);

當然現在vw已經相容除了oprea所有主流瀏覽器了,可以放心使用,要比rem使用起來簡單多了,不管是多大的設計稿,視口寬度都等於100vw,相當於是把最大視口寬度分成了100份;