移動端如何進行rem的適配

網(wǎng)上很多都說會pc網(wǎng)頁開發(fā),也就會了mobile網(wǎng)頁開發(fā)。那么實際呢也是如此,但是對于新手來說卻摸不著頭腦無從下手,一直糾結(jié)于適配的問題,那么這里就來展示下rem適配。

展示rem適配代碼

 //rem適配
 (function () {
        var  styleN = document.createElement("style");
        var width = document.documentElement.clientWidth/16;
        styleN.innerHTML = 'html{font-size:'+width+'px!important}';
        document.head.appendChild(styleN);
    })();

  • 這什么意思呢?就是把手機屏幕分成16份,每份設置為font-size,就是每份代表1rem。

  • 那我們要怎么用呢?直接在代碼中引入普通js一樣就可以了。

  • 那寫css的時候要怎么寫呢?寫css的時候根據(jù)設計師給的圖 寬度/16 就是1rem了,這又是什么意思呢?可以這么理解:

    image

如果設計師給的圖是750px;那么1rem就是750/16=46.875px;也就是1rem代表46.875px;那如果在css中要寫

.box{
  width:60px;
}

要怎么寫呢?這么寫

.box{
  width:1.28rem;
}

呃呃,這個1.28怎么來的?60px/46.875px*1rem = 1.28rem就是這么來的。
曉得沒呢,那這樣是不是每一個px轉(zhuǎn)rem都要這么算呢?
沒錯,就是都要這么算,那是不是很麻煩呢,哈哈,不要著急,這個時候呢就有了less編譯等
這里就以less編譯舉個例子:
index.less

@rem:46.875rem;
body{
    width: 60/@rem;
}

編譯后
index.css

body {
  width: 1.28rem;
}

其他適配方案:

第一種方法:考慮了m端屏幕旋轉(zhuǎn)的問題.對兼容性做出了一定的處理,具體看代碼
export function rem (doc, win) {  
  let docEl = doc.documentElement;  //考慮以及兼容了 屏幕旋轉(zhuǎn)的事件
  let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';  
  let recalc = function () { 
     var clientWidth = docEl.clientWidth;          
     if (!clientWidth) return;           
     if (clientWidth >= 750) {
                 docEl.style.fontSize = '100px';
      } else {
                 docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
            }
      };   if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);     // 屏幕大小以及旋轉(zhuǎn)變化自適應
    doc.addEventListener('DOMContentLoaded', recalc, false);     // 頁面初次打開自適應
    recalc();
};


第二種方法:采用html標簽的offsetWidth長度計算
export function rem() {  
  var fz = document.querySelector('html').offsetWidth / 7.5; //設計圖 750 1rem=100px
  document.querySelector('html').style.fontSize =
    fz <= 100 ? fz + 'px' : '100px';  window.onresize = function() {
    rem();
  };
};

第三種方法:采用window.innerWidth計算,設置了body fontSize防止字體繼承,使頁面字體過大
export function rem() { 
  document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px'; //1rem = 100px
  document.body.style.fontSize = '14px';// 在body上將字體還原大小,避免頁面無樣式字體超大
}

現(xiàn)在回過頭來看,感覺自己以前寫復雜了,其實道理很簡單;

就是利用vw,rem隨屏幕,或者跟字體正比變化的特性;

1.就是開發(fā)的時候用的750設計稿的尺寸;單位是px;

2.然后編譯工具,如postcss 會自動將px單位轉(zhuǎn)成對應rem和vw單位;

3.如果是vw很好轉(zhuǎn)轉(zhuǎn)行,比如寫的40px;40/750 vw就完了;

4.如果是rem就多一步罷了;要用js計算出根字體大小,并設置給html;

*正常是 375 ,16px;所以比例常數(shù)就是 : 屏幕尺寸/75032 ,也就是html 根字體 大?。?/em>

e.g : postcss將40px轉(zhuǎn)化成rem單位; 1rem/(屏幕尺寸/75032) = x/40*

x 就等于 40/(屏幕尺寸/75032) rem;*

*動態(tài)改變(屏幕尺寸/75032) 這個 根字體 就可以動態(tài)適應屏幕了!


看了一周的rem手機適配方案;搞的腦殼痛;現(xiàn)在總于搞明白了!建議一次性看完本片文章再去百度相關知識點!不要離開!


基礎點:rem相對根節(jié)點<html>字體的大小。所以不用px;

根字體:<html>字體的大小px;

px:你就當成cm(厘米)這樣的東西吧;

基準:750設計稿;


這是方案的基礎理論,在這個基礎上,我們還要搞明白,到底要干一件什么事情!

目標一 、手機適配:就是頁面上的尺寸,無論高度,還是寬度,還有字體,隨屏幕的寬度變化!這里是屏幕寬度!是不是想到了vw,對,就是這個意思;——最大程度在各個尺寸屏幕上還原設計稿

目標二、px轉(zhuǎn)換成rem:一般UI給的設計稿寬度大小是750,所以,我們想直接寫上面UI標記的尺寸;——最大程度減少工作

為什么選擇rem?

很久之前沒有vw,怕vw的兼容問題,就用了rem;也就是:rem的兼容性>vw的兼容性;(vw的適配方案!非常簡單!);

還有一種就是自己寫百分比,不但要自己算哭,而且很不優(yōu)雅(我以前就是這樣干的,有時候為了讓高度和寬度的百分比一樣,我還把高度寫成0,{padding:40%,width:40%,height:0})。


一、理論基礎!

實現(xiàn)目標一

用rem就可以了吧!因為rem就可以隨根字體大小改變而改變,從而實現(xiàn)了自適應的功能。

但是,但是,重點來,如果,根字體的大小默認是16px;那么,我們的1rem;就永遠是16px,懂么?也就是如果設計稿是750(放大了一倍,iphone是375pt),我們想要個50%的大小:

50%*357px/16=11.718rem(這里還要自己換算,要哭)

如果我們寫一個11.718rem的寬度,然而這只能在能iphone6還原設計稿,也就是只有在iphone6上這樣的寬度才剛好占一半;

那么問題來了,如果在每個屏幕上都是50%呢,直接改變根字體大小(16px)不就完了么?。?;11.718rem永遠還是那個11.718rem,不用擔心;

實現(xiàn)目標二、

用工具,webpack,postcss,postcss-pxtorem

二、準備主要工具!

viewport: 建議自行百度;

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

vue-cli: 用這個主要是用webpack,這個構(gòu)建工具大大降低了webpack的使用難度;快速構(gòu)建出一個前端項目。(親測,真的很快);

postcss: 官網(wǎng)解釋:PostCSS is a tool for transforming styles with JS plugins,就是postcss用js插件幫你轉(zhuǎn)換css樣式的一個工具。比如,這里的把你的文件里面16px替換成1rem(根大小默認16px的情況);這樣你就不用自己去算了!

postcss-pxtorem: postcss的一個插件,主要是幫你把px轉(zhuǎn)換成對應的rem;

然后:還要用js代碼去動態(tài)算根目錄應該有的字體大小,反正就是一段js代碼去動態(tài)獲取屏幕寬度!

超級麻煩的一種方案推薦:(可以自己用淘寶彈性布局方案lib-flexible實踐; 或者看flexible.js 移動端自適應方案 - 簡書;其實這js的作用就是幫你根據(jù)屏幕大小——動態(tài)改變根字體大小和data-dpr值!但是rem的值還是要你自己算哦,或者用其他工具?。?/p>

三、rem——開始干!

第一步,先用vue-cli快速構(gòu)建出一個項目,然后,安裝postcss,postcss-pxtorem,postcss-loader,postcss-import,postcss-url;看不懂的同學看這個吧(如何在Vue項目中使用vw實現(xiàn)移動端適配(轉(zhuǎn)) - 簡書

第二步,在項目根目錄下添加.postcssrc.js文件,在里面寫上

module.exports = { plugins: { 'postcss-pxtorem': { rootValue: 32, propList: ['*'], minPixelValue: 2 } }};

就完了。簡單解釋下,免得你們百度半天,建議自己在npm官網(wǎng)上看postcss-pxtorem的文檔。rootValue,這里就是根目錄的字體大小是32px,這里為啥設置成32呢,因為一般設計稿是750,比iphone6的大一倍,所以設置成16的兩倍,就是32px;proplist就是那些屬性需要轉(zhuǎn)換成rem,這里是全部的意思;

比如你可選擇設置; propList: ['font', 'font-size', 'line-height', 'letter-spacing']

minPixelValue就是最小轉(zhuǎn)換單位,這是最小轉(zhuǎn)換單位是2px的意思;

第三步,動態(tài)設置根字體大小!一段簡單的js插入在head里面;

(function() {

function autoRootFontSize() {

    document.documentElement.style.fontSize =        Math.min(screen.width,document.documentElement.getBoundingClientRect().width)  /  750 * 32 + 'px';

      // 取screen.width和document.documentElement.getBoundingClientRect().width的最小值;除以750,乘以32;懂的起撒,就是原本是750大小的32px;如果屏幕大小變成了375px,那么字體就是16px;也就是根字體fontSize大小和屏幕大小成正比變化!是不是很簡單

}

window.addEventListener('resize', autoRootFontSize);

autoRootFontSize();

})();

這里,我想說的是完全可以用vw去設置根字體大小,26px/375px=4.267vw;就不用js去算了!

html{font-size:4.267vw}; //因為這個字體大小完全是隨屏幕正比變化;

四、vw——開始干!

vw的方案就簡單多了,因為vw本來就相對屏幕的百分比,所以我們不用再去動態(tài)的改變根字體大小了,只需要把750上的px大小轉(zhuǎn)換成對應的vw值就完了,這一步交給postcss工具就可以!

所以只需要兩步!

第一步,先用vue-cli快速構(gòu)建出一個項目,然后,安裝postcss,postcss-pxtorem,postcss-loader,postcss-import,postcss-url;看不懂的同學看這個吧(如何在Vue項目中使用vw實現(xiàn)移動端適配(轉(zhuǎn)) - 簡書

第二步,在項目根目錄下添加.postcssrc.js文件,在里面寫上

 module.exports = 
{ "plugins": 
  {
     "postcss-import": {}, 
     "postcss-url": {}, 
     "postcss-aspect-ratio-mini": {},
     "postcss-write-svg": { utf8: false }, 
     "postcss-cssnext": {}, 
     "postcss-px-to-viewport": 
        { 
          viewportWidth: 750, 
          unitPrecision: 3, 
          viewportUnit: 'vw', 
          selectorBlackList: ['.ignore', '.hairlines'], 
          minPixelValue: 1, 
          mediaQuery: false 
        }, 
     "postcss-viewport-units": {}, 
  }
}

viewportWidth是你設計稿的大小750,然后unitPrecision是vw值保留的小數(shù)點個數(shù);

五、騷做總結(jié)!

是不是看完腦殼昏戳戳的!那就對了~

首先明白一件事:px就像cm一樣,1px永遠是1px;1cm永遠是1cm;

那么我們從目標再反推一道邏輯:

我們想要的結(jié)果很簡單: 一個元素的寬度(px) / 屏幕寬度(px) = 定值 (這個定值就是設計稿上面的值比例定值);

——所以要做就是:屏幕變寬,要讓元素寬度就變寬。

然鵝,我們寫的代碼里面的px是不可能變的(取的750設計稿上面的尺寸);那么postcss編譯出來的rem值也是不變的;

我們是怎么把設計稿里面的40px換算成相應rem的呢;你只要記住根字體大小的值(瀏覽器的默認是16px,現(xiàn)在設置成的32px)就是1rem;這交給工具同一去算;

得到:元素的寬度(px) = 元素的寬度(rem) ??32; 所以這個32是你必須要設置在postcss-pxtorem里面的;這樣它就可以幫你算;

又因為: *元素的寬度(rem) ?? 根字體大?。╬x) = 元素的寬度(px) *

元素的寬度(px) 變大, 元素的寬度(rem) 不變,那就只有改變根字體大小(px) ,變大;具體怎么變,上面的js代碼已經(jīng)解釋了;

——所以我們做的就是:屏幕變寬,讓根字體大?。╬x) 變寬,元素寬度就變寬。

750屏幕下是寫的樣式大小是1:1, 所以

又因為我們想要*:根字體大?。╬x) / 屏幕寬度(px) = 32 / 750 *

所以: 根字體大?。╬x) = 32 / 750 ?? 屏幕寬度(px)

一個元素的寬度(px) / 屏幕寬度(px) = 定值

→ 根字體大小(px) ??元素的寬度(rem)/ 屏幕寬度(px)

→ 32 / 750 ?? 屏幕寬度(px) ??元素的寬度(rem)/ 屏幕寬度(px) 等于什么??

得到的的是一個與屏幕大小無關的定值!

化簡: 元素的寬度(rem)??32 / 750 = 元素的寬度(px) / 750 ——不就是設計稿上面的比例么?。?!


驗******證以上操作出來的結(jié)果是否符合預期也很簡單:

比如一個img的寬,高,在iphone6上的尺寸(審查元素的大??!px單位):

根字體:16px; postcss算出來的rem值是2.5rem; 2.5*16=40px; 實際上也是40px;

——得到元素實際大小 40??40(px), 屏寬是375;比例是40/375=0.10667;

在iphone5上的尺寸(審查元素的大??!px單位):

根字體:13.6533px; postcss算出來的rem值是2.5rem; 2.5*13.6533=34.13px; 實際上也是34.13px;

——得到元素實際大小 34.13??34.13(px), 屏寬是320;比例是34.13/320=0.10665;

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

相關閱讀更多精彩內(nèi)容

  • 現(xiàn)在回過頭來看,感覺自己以前寫復雜了,其實道理很簡單; 就是利用vw,rem隨屏幕,或者跟字體正比變化的特性; 1...
    會會會會閱讀 43,311評論 16 40
  • 1,先看看網(wǎng)上關于移動端適配講解 再聊移動端頁面適配,rem和vw適配方案! 基礎點:rem相對根節(jié)點 字體的大小...
    _雙眸閱讀 70,848評論 13 51
  • 說到前端頁面的布局方案,可以從遠古時代的Table布局說起,然后來到 DIV+CSS布局,之后有了Float布局,...
    841只閱讀 1,570評論 1 3
  • 什么是Rem rem和em很容易混淆,其實兩個都是css的單位,并且也都是相對單位,現(xiàn)有的em,css3才引入的r...
    tobAlier閱讀 28,134評論 2 38
  • 昨晚的夢境很美,只記得在某個過海關的機場,有一只大貓。 這個貓看似活的又不像活物,應該是帶有仙氣吧,因為它飄在機場...
    刀之林夕土竟閱讀 190評論 0 0

友情鏈接更多精彩內(nèi)容