1. 程式人生 > >移動web適配之rem

移動web適配之rem

前言

提到rem,大家首先會想到的是rm,px這類的詞語,大多數人眼中這些單位是用於設定字型的大小的,沒錯這的確是用來設定字型大小的,但是對於rem來說它可以用來做移動端的響應式適配哦。

相容性

先看看相容性,大部分主流瀏覽器都支援,可以安心的往下看了。

rem設定字型大小

rem是(font size of the root element),官方解釋

意思就是根據網頁的跟元素來設定字型大小,和em(font size of the element)的區別是,em是根據其父元素的字型大小來設定,而rem是根據網頁的跟元素(html)來設定字型大小的,舉一個簡單的例子,

現在大部分瀏覽器IE9+,Firefox、Chrome、Safari、Opera ,如果我們不修改相關的字型配置,都是預設顯示font-size是16px即

html {
    font-size:16px;
}

那麼如果我們想給一個P標籤設定12px的字型大小那麼用rem來寫就是

p {
    font-size: 0.75rem; //12÷16=0.75(rem)
}

基本上使用rem這個單位來設定字型大小基本上是這個套路,好處是加入使用者自己修改了瀏覽器的預設字型大小,那麼使用rem時就可以根據用的調整的大小來顯示了。 但是rem不僅可以適用於字型,同樣可以用於width height margin這些樣式的單位。下面來具體說一下

rem進行螢幕適配

在講rem螢幕適配之前,先說一下一般做移動端適配的方法,一般可以分為: 1 簡單一點的頁面,一般高度直接設定成固定值,寬度一般盛滿整個螢幕。 2 稍複雜一些的是利用百分比設定元素的大小來進行適配,或者利用flex等css去設定一些需要定製的寬度。 3 再複雜負責一些的響應式頁面,需要利用css3的media query屬性來進行適配,大致思路是根據螢幕不同大小,來設定對應的css樣式。 上面的一些方法,其實也可以解決螢幕適配等問題,但是既然出來的rem這個新東西,也一定能兼顧到這些方面,下面具體來說具體使用rem:

rem適配

先看一個簡單的例子:

.con {
      width: 10rem;
      height: 10rem;
      background-color: red;
 }
<div class="con">
        
</div>

這是一個div,寬度和高度都用rem來設定了,在瀏覽器裡面是這樣顯示的,  可以看到,在瀏覽器裡面width和height分別是160px,正好是16px * 10,那麼如果將html根元素的預設font-size修改一下呢?

html {
    font-size: 17px;
}
.con {
      width: 10rem;
      height: 10rem;
      background-color: red;
 }
<div class="con">
        
</div>

再來看看結果:

這時width和height都是170px,這就說明了將rem應用與width和height時,同樣適用與rem的特性,根據根元素的font-size值來改變自身的值,由此我們應該可以聯想到我們可以給html設定不同的值,從而達到我們css樣式中的適配效果。

rem數值計算

如果利用rem來設定css的值,一般要通過一層計算才行,比如如果要設定一個長寬為100px的div,那麼就需要計算出100px對應的rem值是 100 / 16 =6.25rem,這在我們寫css中,其實算比較繁瑣的一步操作了,不過這其實都不是事。 想想我們現在的工程,哪個沒有用構建的,前端構建中,完全可以利用scss來解決這個問題,例如我們可以寫一個scss的function px2rem即:

@function px2rem($px){
    $rem : 37.5px;
    @return ($px/$rem) + rem;
}

這樣,當我們寫具體數值的時候就可以寫成:

height: px2rem(90px);
width: px2rem(90px);;

看到這裡,你可能會發現一些不理解的地方,就是上面那個rem:37.5px是怎麼來的,正常情況下不是預設的16px麼,這個其實就是頁面的基準值,和html的font-size有關。

rem基準值計算

關於rem的基準值,也就是上面那個37.5px其實是根據我們所拿到的視覺稿來決定的主要有以下幾點原因:

1 由於我們所寫出的頁面是要在不同的螢幕大小裝置上執行的

2 所以我們在寫樣式的時候必須要先已一個確定的螢幕來作為參考,這個就由我們拿到的視覺稿來定

3 假如我們拿到的視覺稿是以iphone6的螢幕為基準設計的

4 iPhone6的螢幕大小是375px,

rem = window.innerWidth  / 10

這樣計算出來的rem基準值就是37.5(iphone6的視覺稿),這裡為什麼要除以10呢,其實這個值是隨便定義的,假如不除以10,根據我們算出來的基準值會偏大,這樣在設定html的font-size時候會偏小,我們知道瀏覽器的font-size如果小於12px就顯示不出效果了,在這裡列舉一下其他手機的

iphone3gs: 320px / 10 = 32px

iphone4/5: 320px  / 10 = 32px

iphone6: 375px  / 10 =37.5px

動態設定html的font-size

現在關鍵問題來了,我們該如何通過不同的螢幕去動態設定html的font-size呢,這裡一般分為兩種辦法

1 利用css的media query來設定即

@media (min-device-width : 375px) and (max-device-width : 667px) and (-webkit-min-device-pixel-ratio : 2){
      html{font-size: 37.5px;}
}

2 利用javascript來動態設定 根據我們之前算出的基準值,我們可以利用js動態算出當前螢幕所適配的font-size即:

document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';

然後我們看一下之前那個demo展示的效果

.con {
      width: px2rem(200px);
      height: px2rem(200px);
      background-color: red;
}
<div class="con">
        
</div>
document.addEventListener('DOMContentLoaded', function(e) {
                document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
}, false);

iPhone6下,正常顯示200px

在iphone4下,顯示169px

由此可見我們可以通過設定不同的html基礎值來達到在不同頁面適配的目的,當然在使用js來設定時,需要繫結頁面的resize事件來達到變化時更新html的font-size。

rem適配進階

我們知道,一般我們獲取到的視覺稿大部分是iphone6的,所以我們看到的尺寸一般是雙倍大小的,在使用rem之前,我們一般會自覺的將標註/2,其實這也並無道理,但是當我們配合rem’使用時,完全可以按照視覺稿上的尺寸來設定。

1 設計給的稿子雙倍的原因是iphone6這種螢幕屬於高清屏,也即是裝置畫素比(device pixel ratio)dpr比較大,所以顯示的畫素較為清晰。

2 一般手機的dpr是1,iphone這種高清屏是2,可以通過js的window.devicePixelRatio獲取到當前裝置的dpr,所以iphone6給的視覺稿大小是(*2)750×1334了。

3 拿到了dpr之後,我們就可以在viewport meta頭裡,取消讓瀏覽器自動縮放頁面,而自己去設定viewport的content例如

meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');

4 設定完之後配合rem,修改

@function px2rem($px){
    $rem : 75px;
    @return ($px/$rem) + rem;
}

雙倍75,這樣就可以完全按照視覺稿上的尺寸來了。不用在/2了,這樣做的好處是:

1 解決了圖片高清問題。

2 解決了border 1px問題(我們設定的1px,在iphone上,由於viewport的scale是0.5,所以就自然縮放成0.5px)

rem進行螢幕適配總結

下面這個網址是針對rem來寫的一個簡單的demo頁面,大家可以在不同的手機上看一下效果

但是rem也並不是萬能的,下面也有一些場景是不適於使用rem的

1 當用作圖片或者一些不能縮放的展示時,必須要使用固定的px值,因為縮放可能會導致圖片壓縮變形等。

2 再設定backgroundposition或者backgroundsize時不宜使用rem。

在列舉幾個使用rem的線上網站: