移動端rem怎樣適配

中單小蘿蔔發表於2018-11-05

向貓咪提問

一般我們在公司開發頁面,UI設計圖是出750px的圖,也就是基於Iphone 6 設計的圖。如果我們用如果得當的配置,UI圖上的東西是多少px,我們就寫多少px,這是程式設計師最方便的。但是這個是怎麼配置的呢?

移動端rem怎樣適配

不要方,其實很簡單,跟著思路走起來~~~

如果不配置,我們在CSS裡寫多少px才能還原設計圖?

來舉個例子~

假設現在圖上有個寬度100px的按鈕,UI圖是750px的圖。

答案是我們應該寫 100px / 2 = 50px。css裡width = 50px; 就這樣。

那為什麼是100px除以2呢???因為iPhone的dpr = 2。

那什麼是dpr?

dpr的全稱是window.devicePixelRatio,它等於物理畫素 / dips。其實就是一個比例。(物理畫素就是一個個的小格子,用來顯示不同顏色的。dips可以理解為虛擬畫素,就像我們寫的css。實在理解不了就忽略吧...)

從iphone4開始,iphone就是dpr就等於2了。所以其實就是把UI圖除以2,就是你應該在css寫多少px。

是不是很簡單~~~

移動端rem怎樣適配

以上是怎麼還原設計稿的px單位,那現在又有個問題來了,我們不是所有人都是用的iphone6吧,還是其他各種螢幕大小的手機,比如極端一點的iphone 4、iphone 6s plus...各種各樣螢幕大小的手機,難道每個手機上顯示一樣大小的文字和圖片?那好惱火,所以,我們要適配!!!

咋個適配呢?

方法就像兵器,各種各樣都有,看你自己根據實際情況選哪個,下面是方法:

  1. 100%佈局適配
  2. rem做適配
  3. ...

先來說rem

開課咯~,聽講聽講~(敲黑板)

移動端rem怎樣適配

還是來舉個上面相同的例子,假設現在圖上有個寬度100px的按鈕,UI圖是750px的圖。為了不同大小的螢幕適配,按鈕我們應該寫多少rem呢? rem就是根元素的字型大小!根元素就是<html>標籤。網頁<html>的預設字型大小是 16px。也就是瀏覽器預設的字號16px。

換算方式:1rem = 16px。所以100px = 100 / dpr / 16 = 3.125rem。 所以按鈕的寬度在css裡,我們就應該寫3.125rem。螢幕上按鈕的尺寸跟iphone 6的比例就和UI圖上一樣了。

但是怎麼去改變根字型的大小呢?

1、用@media媒體查詢設定不同螢幕的根字型大小,要寫很多css程式碼,因為螢幕大小那麼多,難以一一寫全。

2、我推薦寫js,幾行就搞定

下面就是隨著螢幕大小改變根字型大小的js。推薦寫在入口頁面裡,

(function() {
 function autoRootFontSize() {
  document.documentElement.style.fontSize = Math.min(screen.width, document.documentElement.getBoundingClientRect().width) / 750 * 32 + 'px';}
  window.addEventListener('resize', autoRootFontSize);
  autoRootFontSize();
})();
複製程式碼

當頁面開啟和發生變化時,就會執行resize事件,這裡面用到了getBoundingClientRect屬性(可以上MDN上查),它其實就是返回一個物件的left、top、right、bottom、width、height,單位為畫素。(請注意相容問題,IE8及一下沒有width、height)。螢幕寬度和html的寬度取個最小值(其實大部分情況兩者是相同的)。移動端通常是除以32,為了讓字更大一點,清晰一些。

好啦,根字型隨著螢幕大小而變化啦,那麼不可能每次寫css還要去換算應該寫多少rem吧,那麼多css,要寫哭,所以建議用css前處理器,postcss、less、 sass,如果沒用過,自行查閱其官方文件。

移動端rem怎樣適配

不要方,其實很簡單......下面就介紹我在工作中用到的。

PostCSS是一款使用外掛去轉換CSS的工具。可以處理CSS,通常是結合webpack這些工具一起使用的。我的專案就是用的webpack,在專案根目錄下建一個postcss.config.js檔案,專案會自動去讀取這些配置類檔案,這個js裡的內容是:

module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-pxtorem': {
      rootValue: 32,
      propList: ['*'],
      minPixelValue: 2
    }
  }
};
複製程式碼

這個plugins就是你要用到的外掛,比如這裡用到的兩個外掛autoprefixer、postcss-pxtorem。

autoprefixer就是給css前面加上合適的字首,這點少寫了很多行程式碼是不是。

postcss-pxtorem就是把px轉換成rem,這也就是我們上面根字型改變了,px也可以換算成rem,但是這個外掛就可以根據你的根字型,自動換算rem,是不是很方便。

rootValue就是根字型大小,初始設定為32,在移動端更清晰一點。

移動端我們目前就只用到了這2個外掛。

上面也說了,要結合webpack使用,那麼在webpack裡應該怎麼寫呢?

module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
      },
      {
        test: /\.css/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      }
    ]
}
複製程式碼

直接在css-loader後面這樣加上postcss-loader。就會去處理postcss裡的東西,postcss-loader的安裝命令:npm install --save-dev postcss-loader

(上面use陣列裡面的外掛是從右往左依次執行的,最後執行的是style-loader。這個順序還是有必要知曉一下。)

綜上所述,我們達到的效果就是:

UI圖上是100px,你直接在css裡寫100px,就是這麼簡單。不管什麼大小的螢幕,字型大小會隨之變化,永遠都是最合適的大小。並且,打包後的程式碼,都是有字首的程式碼。簡直不要太爽。

如果有不對的地方,歡迎指正,希望大家喜歡~~

相關文章