06、手把手教Vue--移動webapp適配方案--rem

PS:轉(zhuǎn)載請注明出處
作者: TigerChain
地址: http://www.reibang.com/p/443c6704d8d8
本文出自 TigerChain 簡書 手把手教 Vue 系列

大綱

教程簡介

  • 1啤誊、閱讀對象
    本篇教程適合新手閱讀岳瞭,老手直接略過
  • 2、教程難度
    初級蚊锹,本人水平有限瞳筏,文章內(nèi)容難免會出現(xiàn)問題,如果有問題歡迎指出牡昆,謝謝
  • 3姚炕、Demo 地址:https://github.com/tigerchain/vue-lesson 請看 05、移動webapp適配--rem 這一節(jié)

正文

一丢烘、media query「媒體查詢」

在聊 rem 之前柱宦,我們先看看什么是 media query?

為了適配多種屏幕大到電腦,小到手機等播瞳, css3 中有了多媒體查詢這個功能「是繼承 css2 多媒體類型的思想」掸刊,通過 media query 就可以做響應(yīng)式的開發(fā)

1、media query 的作用

  • 可以檢測 viewport(視窗) 的寬度與高度
  • 可以檢測設(shè)備的寬度與高度
  • 可以檢測設(shè)備的分辨率

2赢乓、media query 的語法

@media not|only mediatype and (expressions) {
    CSS 代碼...;
}

我們可以看到 media query 由四部分組成

  • 1忧侧、關(guān)鍵字:@media
  • 2石窑、操作符:not|only|all 「默認不寫就是 all」
  • 3、媒體類型:mediatype
  • 4蚓炬、表達式:expressions

這里的媒體類型有以下幾種:

描述
all 用于所有多媒體類型設(shè)備
print 用于打印機
screen 用于電腦屏幕松逊,平板,智能手機等肯夏。
speech 用于屏幕閱讀器

一般情況下我們使用 screen 的媒體類型是最多的

舉個例子

我們想讓在屏幕尺寸大于 375px 的設(shè)備上讓 class 為 div1 的背景顯示成紅色经宏,media query 哪下定義

@media screen and (min-device-width : 375px){
    .div1 {
        background-color:red;
    }
}

我們可以針對不同的設(shè)備寬度來設(shè)置不同的樣式 ,這樣就達到了響應(yīng)式布局的效果驯击,現(xiàn)在我們來一個例子說明吧

3烁兰、demo 驗證 media query

效果如下

media query 效果

從上面的效果圖我們可以看到,我們針對不同屏幕寬度就會顯示不同的效果余耽,這就是響應(yīng)式布局缚柏,下面我們使用 media query 來實現(xiàn)這一效果

擼碼實現(xiàn)上述效果

<!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>media-query</title>
  <!-- 重置默認的 css 樣式 ,類似于 reset.css -->
  <link rel="stylesheet" href="../css/normalize.css">
  <!-- https://necolas.github.io/normalize.css/7.0.0/normalize.css -->

  <style>
    .box {
      width:100% ;
      height:80px;
      background-color: red;
    }

    /* 屏幕小于 375 px 則是下面的樣式 */
    @media screen and (max-device-width : 375px){
      .div1 {
        width:25%;
        background-color: green;
        height:80px;
      }
    }

    /* 屏幕大于 376 小于 414 px 則使用下面的樣式 */
    @media screen and (min-device-width : 376px) and (max-device-width:414px){
      .div1 {
        width:50%;
        background-color: blue;
        height:80px;
      }
    }

    /* 小于等于 375px 使用以下樣式  */
    @media screen and (max-device-width: 375px) {
      .menuitem1 {
        height: 100px;
        width: 100%;
        background-color: yellow;
      }
      .menuitem2 {
        height: 100px;
        width: 100%;
        background-color: blue;
      }
      .menuitem3 {
        height: 100px;
        width: 100%;
        background-color: #cceedd;
      }

      .menuitem4 {
        height: 100px;
        width: 100%;
        background-color: black;
      }
    }

    /* 大于等于 376px 使用以下樣式 */
    @media screen and (min-device-width: 376px) {
      .menu {
        display: flex;
      }
      .menuitem1 {
        height: 100px;
        width: 100%;
        background-color: yellow;
      }
      .menuitem2 {
        height: 100px;
        width: 100%;
        background-color: blue;
      }
      .menuitem3 {
        height: 100px;
        width: 100%;
        background-color: #cceedd;
      }
      .menuitem4 {
        height: 100px;
        width: 100%;
        background-color: black;
      }
    }
  </style>
</head>
<body>

  <div id="contnainer" class="box">
    <div class="div1"></div>
  </div>
  <!-- mediaquery 實現(xiàn)響應(yīng)式布局 -->
  <div class="menu">
    <div class="menuitem1"></div>
    <div class="menuitem2"></div>
    <div class="menuitem3"></div>
    <div class="menuitem4"></div>
  </div>

</body>
</html>

以上代碼就實現(xiàn)了上述效果圖碟贾,代碼注釋清楚币喧,這里也不多說了

二、rem「font size of the root element」

1袱耽、什么是 rem

rem 就是根據(jù)網(wǎng)頁根元素「html」來設(shè)置字體大小,這有什么用呢杀餐?這是移動 webapp 的最佳的適配方案「目前來說」,既然說是最佳的適配方案朱巨,那肯定還有別的適配方案史翘,先看看都有那些適配方案吧

  • 1、viewport縮放「被廢棄了」
  • 2冀续、寬度固定兩邊留白「體驗很差」
  • 3琼讽、響應(yīng)式布局「工作量太大,針對不同的分辨率寫一套 android 下估計開發(fā)者就瘋了」

2洪唐、如何適配

我們先來看一個簡單的例子吧钻蹬,然后就能得到一些啟發(fā)和感悟

  • 1、新建一個 rem.html 然后輸入以下內(nè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">
  <!-- 重置默認的 css 樣式 凭需,類似于 reset.css -->
  <link rel="stylesheet" href="../css/normalize.css">
  <title>rem demo</title>

  <style>
    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      text-align: center;
    }
    .test {
      font-size: 16px;
      line-height: 100px;
    }
  </style>
</head>
<body>
  
  <div class='box'>
    <span class="test">測試</span>
  </div>

</body>
</html>

很簡單就是一個寬高為 100px 的 div 并且里面有一個居中的文字大小為 16px

  • 2问欠、運行查看結(jié)果
px 顯示效果

從圖中我們可以看到,不管我們是什么分辨率的機型下粒蜈,div 寬高都為 100px顺献,這是不合理的,根本就沒有適配「就是寫死的呀」

  • 3枯怖、由于 2 中的效果是寫死的注整,我們來看看 rem 是如何適配的,稍微把代碼改一下

我們知道 rem 和 html 下的 font-size 有關(guān),我們來改代碼吧

<!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">
  <!-- 重置默認的 css 樣式 肿轨,類似于 reset.css -->
  <link rel="stylesheet" href="../css/normalize.css">
  <title>rem demo</title>

  <style>
     html {
       font-size: 16px;
     }
    .box {
      width: 10rem;
      height: 10rem;
      background-color: red;
      text-align: center;
    }
    .test {
      font-size: 1rem;
      line-height: 10rem;
    }
  </style>
</head>
<body>
  <div class='box'>
    <span class="test">測試</span>
  </div>
</body>
</html>

ps: 這里說明幾點

為什么這里 font-size 要寫成 16px ,因為大部分瀏覽的默認字體都是顯示 16px,我們從 chrome 調(diào)試工具中可以看到

chrome 默認的 font-size

html 默認的 font-size 大小就 = 1rem , 從上面代碼我們可以看到 box 的寬高都為 10rem 即 160px ,我們來驗證一下,運行看結(jié)果

沒有改變 rem

果然是 160px「肯定在別的分辨率上也是 160px」借浊,這有個毛用呀,不就是把 100px 轉(zhuǎn)化成 160px 了嗎萝招?還不是沒有適配呀「大家是不是有這個疑問」,別急馬上揭曉答案

我們可以想一下存捺,rem 和 font-size 有關(guān)槐沼,那么如果我們能動態(tài)的修改 font-size 的大小,那么以 rem 為單位的寬高等不就自動適配了嗎捌治。我們來一下修改 font-size 的效果

修改 font-size

看到了吧岗钩,我們手動修改 font-size 的值 div 的寬高就會動態(tài)改變「如果在不同分辨率的手機上設(shè)置不同和 font-size 那不就達到適配的效果了」

三、適配手段

我們知道只要動態(tài)的修改 font-size 使用 rem 就可以適配多種手機了

  • 1肖油、通過 media query 來設(shè)置 font-size,比如:
html {
    font-size : 20px;
}
@media only screen and (min-width: 401px){
    html {
        font-size: 25px !important;
    }
}
@media only screen and (min-width: 450px){
    html {
        font-size: 26.75px !important;
    }
}
@media only screen and (min-width: 481px){
    html {
        font-size: 30px !important; 
    }
}
  • 2兼吓、通過 js 來設(shè)置

估計上面的方法能把人寫瘋,特別對于 android 這個多樣機型來說「一般只適配常用的分辨率」森枪,那就有了下面的方法视搏,使用 js 來動態(tài)設(shè)置 font-size

再說 js 動態(tài)修改 font-size 之前,先推導(dǎo)下 px 轉(zhuǎn)化成 rem 的公式:

比如:1rem = 16px「rem 的基準值」 ; 48px = 48/16 = 3rem,

所以得出:

rem = 需要轉(zhuǎn)化的px/rem基準值

rem 基準值「和 html 的 font-size 有關(guān)」如何算县袱,這里給出一個比較常見的做法浑娜,就是用設(shè)計稿的屏幕寬度/10 ,原則上除以多少都可以,除以 10 是為了好除「業(yè)界基本上也是這樣做的」式散,比如以 iPhone 6p「414*736」 為例子筋遭,那么 rem 的基準值就是 414/10 = 41.4px,然后我們就是要不停的改變這個頁面基準值的值即可,我們只要記住一點,rem 的基準值是根據(jù)設(shè)計稿來決定的

我們也知道了暴拄,如果把一個 px 轉(zhuǎn)化成 rem 那么就是使用 px/rem基準值漓滔,這樣界面中的 css 中有太多的 px ,如果一個個除下來人頭發(fā)都白了「也不一定能除完乖篷,當然網(wǎng)上也有在線轉(zhuǎn)換網(wǎng)站响驴,就是這樣也累呀」,我們可以使用 sass「css 擴展語言」 來解決這個問題

1那伐、sass 的安裝

gem install sass
gem install compass

以上安裝速度如果慢的話罕邀,可以切換成淘寶的 gem「安裝基于ruby的軟件」源

  • 3畅形、查看是否安裝成功
sass-v

如果看到這個,就證明 sass 安裝成功了

2日熬、寫個 demo 感受一下

  • 1、新建一個 usesass.html
<!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">
  <link rel="stylesheet" href="../css/normalize.css">
  <link rel="stylesheet" href="../css/usesass.css">
  <title>使用 sass </title>
</head>
<body>

  <div class="box">
    <div class="item"><span>1</span></div>
  </div>

</body>
</html>

細心的朋友會發(fā)現(xiàn)肾胯,我們這里引入了一個 usesass.css 樣式文件竖席,哪來的耘纱?目前這個文件是不存在的,完后我們使用 sass 直接轉(zhuǎn)換成普通的 css 文件即可

  • 2毕荐、在 css 目錄下新建 usesass.scss 文件

scss 和 sass 文件區(qū)別束析,前者對格式?jīng)]有嚴格要求,后者對格式有嚴格的要求「沒有大括號等憎亚,這里我們使用 scss」

.box{
  background-color: red;
  width: 100px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.item {
  background-color: yellow;
  width:50px;
  height:50px;
}
  • 3员寇、scss 肯定是直接不能使用的,我們要轉(zhuǎn)化一下第美,使用 sass 命令

我們進入到 css 目錄下使用如下命令

sass usesass.scss usesass.css

這樣就會在 css 目錄下創(chuàng)建一個 usesass.css 文件并且把 sass 轉(zhuǎn)化成 css 了,我們看看這個 css 文件

.box {
  background-color: red;
  width: 100px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center; }

.item {
  background-color: yellow;
  width: 50px;
  height: 50px; }

看起來和上面的 sass 文件是一毛一樣的「原因是我們沒有使用 sass 的擴展語法蝶锋,sass 是兼容所有的版本的 css 的」

  • 4、運行一下看結(jié)果
sass 轉(zhuǎn) css

沒有什么毛病什往,sass 成功轉(zhuǎn)化成 css 并且顯示出結(jié)果了

3扳缕、使用 sass 來轉(zhuǎn)化 px--rem 梯刚,并且使用 js 動態(tài)設(shè)置 font-size

  • 1逗威、提供 px2rem() 函數(shù)

在 sass 中我們可以使用函數(shù)挽放,我們定義一個函數(shù)用來轉(zhuǎn)化 px 到 rem纤虽,這里以視覺稿為 iphone 6p「414*736」 為例子京革,那么 rem 的基準值就是 41.4px 绳泉,我們在 usesass.sass 中添加如下代碼,并且修改 box 的寬高 px 為 rem「調(diào)用 px2rem()方法」

@function px2rem($px){
  // rem基準值
    $rem : 41.4px;
    @return ($px/$rem) + rem;
}

.box{
  background-color: red;
  width: px2rem(100px);
  height: px2rem(100px);
  display: flex;
  justify-content: center;
  align-items: center;
}
.item {
  background-color: yellow;
  width:px2rem(50px);
  height:px2rem(50px);
}
  • 2冠跷、使用 js 動態(tài)的修改 font-size 的值

在 usesass.html 添加以下動態(tài)修改 font-size 的代碼

<script>
  // 取得屏幕寬度
  var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
  //動態(tài)設(shè)置 html font-size 值
  document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
</script>
  • 3合是、記得一定要把 sass 轉(zhuǎn)化成 css
sass usesass.scss usesass.css

我們再看看 usesass.css 文件

.box {
  background-color: red;
  width: 2.4154589372rem;
  height: 2.4154589372rem;
  display: flex;
  justify-content: center;
  align-items: center; }

.item {
  background-color: yellow;
  width: 1.2077294686rem;
  height: 1.2077294686rem; }

我們看 px 成功的轉(zhuǎn)化成 rem 了衫樊,這樣我們就可以動態(tài)的修改 rem 了

  • 4飒赃、看看效果吧

先看效果之前,我們?yōu)榱朔奖銣y試科侈,來給動態(tài)修改 rem 添加一個事件吧载佳,否則每次修改分辨率都要重新刷新一下瀏覽器「這里是為了演示添加的代碼」

// 窗口大小改變時的回調(diào)
window.onresize = function(){
  // 取得屏幕寬度
  var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
  //動態(tài)設(shè)置 html font-size 值
  document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
}
使用 js 動態(tài)修改 font-size

依據(jù)前面我們知道,我們是以設(shè)計稿為 iphone 6p 基準來設(shè)置的「在此手機上寬高就是 100 px」臀栈,從上圖可以看到確實在不同的分辨率手機下 box 的寬高等比縮放蔫慧,這就達到了適配的目的,基本上 rem 適配手機 webapp 方法就說完了

四权薯、參考資料

騰訊全端AlloyTeam團隊--移動web適配利器--rem:http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem/


點贊富一生姑躲,轉(zhuǎn)發(fā)富五代,更多文章請關(guān)注我的微信公號來查閱

公眾號:TigerChain

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盟蚣,一起剝皮案震驚了整個濱河市黍析,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屎开,老刑警劉巖阐枣,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡蔼两,警方通過查閱死者的電腦和手機甩鳄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來额划,“玉大人妙啃,你說我怎么就攤上這事】〈粒” “怎么了彬祖?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長品抽。 經(jīng)常有香客問我,道長甜熔,這世上最難降的妖魔是什么圆恤? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮腔稀,結(jié)果婚禮上盆昙,老公的妹妹穿的比我還像新娘。我一直安慰自己焊虏,他們只是感情好淡喜,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诵闭,像睡著了一般炼团。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疏尿,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天瘟芝,我揣著相機與錄音,去河邊找鬼褥琐。 笑死锌俱,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的敌呈。 我是一名探鬼主播贸宏,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼磕洪!你這毒婦竟也來了吭练?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤析显,失蹤者是張志新(化名)和其女友劉穎线脚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡浑侥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年姊舵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寓落。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡括丁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伶选,到底是詐尸還是另有隱情史飞,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布仰税,位于F島的核電站构资,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏陨簇。R本人自食惡果不足惜吐绵,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望河绽。 院中可真熱鬧己单,春花似錦、人聲如沸耙饰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苟跪。三九已至廷痘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間件已,已是汗流浹背牍疏。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拨齐,地道東北人鳞陨。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像瞻惋,于是被迫代替她去往敵國和親厦滤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

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