web移動端UI適配之rem

移動端適配大致兩種,一種是百分比還有一種就是rem脱篙,這里就說說rem適配要怎么做娇钱,原理是什么。先說說為什么要做適配吧绊困。

為何要適配文搂?

眾所周知,手機屏幕的尺寸是五花八門的秤朗,像素密度也是不一樣的煤蹭。同樣是寬度5cm的屏幕,有的手機是720px取视,有的手機是1080px硝皂。

那么假設設計師有個設計稿,寬度是720px的作谭,設計稿里有張圖稽物,這張圖的寬度也是720px。如果我們直接在代碼里寫這張圖的寬度為720px折欠,那我們在720px的手機上看則是正常的贝或,這里我們用一個div做演示


720px屏幕

但是當用戶的手機屏幕寬度有1080px的時候呢吼过?看起來就會像這樣


1080px屏幕

很顯然這跟預期的不一樣,所以我們需要div的尺寸跟隨實際屏幕的寬度進行縮放咪奖。這時盗忱,我們的rem就剛好滿足需求。

rem(font size of the root element)是指相對于根元素的字體大小的單位羊赵。簡單的說它就是一個相對單位售淡。看到rem大家一定會想起em單位慷垮,em(font size of the element)是指相對于父元素的字體大小的單位揖闸。它們之間其實很相似,只不過一個計算的規(guī)則是依賴根元素一個是依賴父元素計算料身。

簡單來說汤纸,我們設定html元素的font-size等于100px時,1rem就等于100px芹血。1 rem = 1 font-size

所以我們只需要獲取屏幕的寬度贮泞,然后根據(jù)寬度和設計稿的比例來計算html的font-size,并設置上去幔烛。
在寫代碼的時候啃擦,就用rem代替px,這樣就可以使div的尺寸根據(jù)html的font-size縮放了

如何計算font-size饿悬?

我們來做幾個設定

  • 設計稿寬度為750px
  • 設計稿中有一個div令蛉,寬度也是750px
  • 理想狀態(tài)(實際屏幕寬度也是750px)下html的font-size是100px,即1rem=100px

那么狡恬,我們先手動寫一下理想狀態(tài)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>rem適配</title>
    
</head>
<style>
    body {
        margin: 0;
        font-size: 16px;;
    }
    html {
        font-size: 100px;
    }
</style>
<body>
    <div style="width: 7.5rem;background: yellow;">
        750px/100 = 7.5rem div
    </div>
</body>
</html>

一定要寫body下的font-size=16px珠叔,或者你需要的,不然body元素下的文字默認大小就會繼承html下的100px弟劲,那樣的話祷安,字體就太大了。

好了兔乞,來看效果


750px下的7.5rem

一切正常汇鞭,我們來把屏幕像素稍微調(diào)大一點,把屏幕寬度調(diào)成900庸追。


900px下的7.5rem

由于我們沒有動態(tài)調(diào)節(jié)html的font-size,所以div的寬度沒有跟隨變化霍骄。那么就來計算一下。

先算出100px是設計稿的多少倍锚国,然后再乘以實際屏幕寬度腕巡,就能算出縮放后的font-size了。
100/750*900 = 120px
現(xiàn)在把120設置上去

html {
     font-size: 120px;
}

搞定~

900px下的7.5rem

好了血筑,rem適配的基本原理你已經(jīng)知道了绘沉,我們開始編碼煎楣。
新建一個flexible.js

// designWidth:設計稿的實際寬度值,需要根據(jù)實際設置
// maxWidth:支持縮放的最大屏幕寬度值车伞,當屏幕寬度超過此值則按最大值進行計算择懂,需要根據(jù)實際設置
// 這段js的最后面有兩個參數(shù)記得要設置,一個為設計稿實際寬度另玖,一個為支持縮放的最大屏幕寬度值困曙,例如設計稿為750,最大寬度為750谦去,則為(750,750)
(function(designWidth, maxWidth) {
    var doc = document
    var win = window
    var docEl = doc.documentElement
    var remStyle = document.createElement('style') // 創(chuàng)建一個style標簽慷丽,用于寫html樣式
    var tid //timeout句柄
  
    // 計算rem的值,即1rem等于多少px
    function refreshRem() {
      var width = docEl.getBoundingClientRect().width // 獲取屏幕寬度
      maxWidth = maxWidth || 750 // 當沒寫maxWidth時鳄哭,默認maxWidth=750
      // 當屏幕寬度超過最大縮放的值要糊,則按最大值處理,不能無限縮放妆丘,那樣會變得很大锄俄,很丑
      if (width > maxWidth) {
        width = maxWidth
      }
      // 計算html的font-size
      var rem = 100 / designWidth * width
      remStyle.innerHTML = 'html{font-size:' + rem + 'px;}'
    }
  
    // 將style標簽插入到文檔
    if (docEl.firstElementChild) {
      docEl.firstElementChild.appendChild(remStyle)
    } else {
      var wrap = doc.createElement('div')
      wrap.appendChild(remStyle)
      doc.write(wrap.innerHTML)
      wrap = null
    }
    // 要等 wiewport 設置好后才能執(zhí)行 refreshRem,不然 refreshRem 會執(zhí)行2次勺拣;
    refreshRem()
  
    win.addEventListener('resize', function() {
      clearTimeout(tid) // 防止執(zhí)行兩次
      tid = setTimeout(refreshRem, 300)
    }, false)
  
    win.addEventListener('pageshow', function(e) {
      if (e.persisted) { // 瀏覽器后退的時候重新計算
        clearTimeout(tid)
        tid = setTimeout(refreshRem, 300)
      }
    }, false)
  
    // 設定body的默認字體大小奶赠,如果不設置,將集成html的字體大小药有,而我們設置的100毅戈,so...
    if (doc.readyState === 'complete') {
      doc.body.style.fontSize = '16px'
    } else {
      doc.addEventListener('DOMContentLoaded', function(e) {
        doc.body.style.fontSize = '16px'
      }, false)
    }
  })(750, 750)
// 這里我們輸入設計稿750px,支持的最大屏幕寬度也是750px塑猖。

可能有同學會問竹祷,為什么只有750px,現(xiàn)在手機都是1080px了羊苟。

其實瀏覽器返回給js和css的px都是抽象的,是根據(jù)真實像素和ppi計算出來的感憾,像我的小米8蜡励,1080px寬度,js獲取的屏幕寬度也只有393px

并且一定要在head元素里寫 <meta name="viewport" content="width=device-width, initial-scale=1.0">
關(guān)于viewport是啥阻桅,可以參閱 https://blog.csdn.net/lamanchas/article/details/78473249

最后凉倚,我們只需要在html中引用此文件即可,也可以用es6的方式引用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>rem適配</title>
    <script src="./flexible.js" type="text/javascript"></script>
    <style>
    body {
        margin: 0;
    }
    </style>
</head>
<body>
    <div style="width: 7.5rem;background: yellow;">
        750px/100 = 7.5rem div
    </div>
</body>
<script>
</script>
</html>

最后效果

25.gif
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嫂沉,一起剝皮案震驚了整個濱河市稽寒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趟章,老刑警劉巖杏糙,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慎王,死亡現(xiàn)場離奇詭異,居然都是意外死亡宏侍,警方通過查閱死者的電腦和手機赖淤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谅河,“玉大人咱旱,你說我怎么就攤上這事”了#” “怎么了吐限?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長褂始。 經(jīng)常有香客問我诸典,道長,這世上最難降的妖魔是什么病袄? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任搂赋,我火速辦了婚禮,結(jié)果婚禮上益缠,老公的妹妹穿的比我還像新娘脑奠。我一直安慰自己,他們只是感情好幅慌,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布宋欺。 她就那樣靜靜地躺著,像睡著了一般胰伍。 火紅的嫁衣襯著肌膚如雪齿诞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天骂租,我揣著相機與錄音祷杈,去河邊找鬼。 笑死渗饮,一個胖子當著我的面吹牛但汞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播互站,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼私蕾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胡桃?” 一聲冷哼從身側(cè)響起踩叭,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后容贝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體自脯,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年嗤疯,在試婚紗的時候發(fā)現(xiàn)自己被綠了冤今。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡茂缚,死狀恐怖戏罢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脚囊,我是刑警寧澤龟糕,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站悔耘,受9級特大地震影響讲岁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衬以,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一缓艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧看峻,春花似錦阶淘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冯勉,卻和暖如春澈蚌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背灼狰。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工宛瞄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人交胚。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓坛悉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親承绸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 說到前端頁面的布局方案挣轨,可以從遠古時代的Table布局說起军熏,然后來到 DIV+CSS布局,之后有了Float布局卷扮,...
    841只閱讀 1,434評論 1 3
  • 了解真實的『REM』手機屏幕適配rem 作為一個低調(diào)的長度單位荡澎,由于手機端網(wǎng)頁的興起均践,在屏幕適配中得到重用。 使用...
    張憲宇閱讀 2,230評論 0 5
  • 在移動互聯(lián)網(wǎng)快速發(fā)展的今天摩幔,手機的種類和尺寸越來越多彤委,作為前端的小伙伴們可能會越來越頭疼,但又不得不去適配一款又一...
    keenjaan閱讀 26,792評論 9 86
  • 題外話 突然被要求教學妹怎么做移動端適配的問題或衡,上一次我寫移動端的東西過去好久了焦影,于是又面向百度了一波,網(wǎng)上感覺還...
    鄭虎三閱讀 565評論 0 10
  • 我們總是焦慮封断,抱怨生活的不公平斯辰,覺得自己就是那個最失敗的人∑绿郏可你真的認真對比過嗎彬呻?你可能不知道,有多少人正羨慕著你...
    楓河閱讀 52評論 0 1