移動端為什么要做適配
移動端相對PC端來說大部分瀏覽器內核都是基於Webkit的,所以大部分都支持CSS3的最新語法。但是由於手機的屏幕尺寸和分辨率都不太一樣(尤其是安卓),所以不得不對不同分辨率的手機做適配來達到近似的展示效果。
一般來說,UI只會給我們提供一份設計圖,目前比較多的是參考手機淘寶的方案給一份750px寬的設計稿,而我們前端要做的就是在不同分辨率的手機上以同樣的效果展示這份設計稿。
在講適配方案之前,有幾個基本的移動端開始相關的知識點得了解一下
- rem單位: 說到rem這個單位就不得不提一下在它之前出現的一個類似單位em,em時相對於父級font-size的相對單位,而rem是相對於根節點html的相對單位,也就是說,當html的font-size為12px時,某一個元素的font-size設為1rem也就是等同於12px了。正因為rem單位的這一特性,從而讓它可以成為移動端適配的一個關鍵單位。
- vw單位:相對於視窗的寬度,視窗寬度是100vw,與整個單位類似的是wh,就是視窗高度,視窗高度時100vh。更詳細的特性可以參考視區相關單位vw, vh..簡介以及可實際應用場景
- 物理像素: 也可以說是設備無關像素,例如iPhone6的分辨率(750x1334)指的是物理像素
- 邏輯像素: 是瀏覽器使用的抽象單位,狀態是可變的,例如在PC瀏覽器調試面板上我們可以看到iPhone6的物理像素為(375x667)
- 物理像素與邏輯像素的關系就是設備像素縮放比dpr
適配思路
1、使用CSS的@media媒體查詢設置在不同屏幕尺寸下現實不同的效果,類似於這樣:
@media only screen and (min-width: 375px) {
.logo {
width : 62.5px;
}
}
@media only screen and (min-width: 360px) {
.logo {
width : 60px;
}
}
@media only screen and (min-width: 320px) {
.logo {
width : 53.3333px;
}
}
首先,這樣只照顧了固定分辨率的機型,肯定是不夠的,而且,如果針對頁面上的每一個元素寫這么多套適配也不現實,媒體查詢還是比較適合PC端不同分辨率屏幕之間的適配。
2、使用css的單位rem,類似於這樣:
@media only screen and (min-width: 375px) {
html {
font-size : 62.5px;
}
}
@media only screen and (min-width: 360px) {
html {
font-size : 60px;
}
}
當然,在實際開發中不可能真的這樣去寫,既然上面已經提到了rem這一單位的特性,那么我們要做的就是根據不同分辨率的設備動態地改變html的font-size就好,也就是1rem代表的大小。比較常見的有兩種方案:
- 通過js動態獲取屏幕的寬度,從而計算出html的font-size,還是拿日常開發常見的750px的設計稿為例:
let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
let htmlDOM = document.getElementsByTagName('html')[0];
htmlDOM.style.fontSize = htmlWidth / 7.5 + 'px';
window.addEventListener('resize', (e) => {
let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
htmlDOM.style.fontSize = htmlWidth / 7.5 + 'px';
})
這樣一來,在375px寬的設備下,html的font-size就是50px,為什么要除以7.5呢,因為這樣設計稿上的數值與需要得到的rem值正好是100倍的關系,這樣便於換算,當然,引入了scss等預處理工具之后,取多少都不重要了,反正用一個處理函數統一轉化一下就可以了,當html的font-size是37.5的時候:
@function px2rem ($px) {
$rem: 75;
@return ($px / $rem) + rem;
}
- 另一種方案同樣是通過vw這一單位實現rem適配
- 上面那種方案說白了就是通過JS動態改變html的font-size的大小,而現在有這么一種單位本身的大小就會隨着屏幕的變化而變化,那豈不是省去了JS操作Html字體大小的代碼!
- 我最開始有點擔心的是兼容性,不過從caniuse上查的的兼容性上來看兼容性還是比較高的,安卓版本大於4.0的瀏覽器都是兼容的的。尤其對於在微信上使用的H5頁面是完全不用擔心兼容性問題的
- 具體實現如下:
設為上面這樣一個數值同樣是為了計算方便,當然不是必須的,在這樣一個數值下,相對應的元素除以100就可以了,寫成scss方法如下/* 當在Ip6下時,100vw代表375px,而視覺稿一般是750px,為了方便算,當html上的1rem代表50px時, 視覺稿上的像素跟rem就存在了100倍的轉化關閉,而此時1vw代表是3.75px,所以html上的font-siez為50/3.75, 約等於13.33333vw,這樣即使不用scss也是比較利於換算的 */ html {background-color: #eee; font-size: 13.33333vw;}
我看了一下網易新聞的h5頁面目前就是使用的這種方案@function px ($px) { @return ($px / 100) + rem; } .demo2 {width: px(200); height: px(200); background-color: #ddd;}
總結
最開始想寫這篇文章是因為之前只知道通過JS動態調節html的font-size這么一種適配方案,剛好前段時間接觸到了公司的一個移動端項目,我只是單獨開發幾個頁面,但我發現是用的vw單位實現的rem方案,剛開始還覺得蠻新奇的,其實后來查資料仔細一想,跟JS那種方案本質上並沒有什么區別,都是以屏幕寬度作為底,動態地調節了html的font-size,也就是1rem的大小。
為了寫這篇文章又回看了慕課網上這個視頻:移動web開發適配秘籍Rem,真的挺感謝這些大牛無私分享的。就像他所說的,移動web開發適配的方案有許多,然而最好的方案一定要掌握。Rem適配方案是我目前所看到的的使用的最多的,多多了解這種方法背后的原理和熟練掌握這種方法還是挺重要的,再次感謝這些大牛的精彩分享,希望我的總結在提升自己的同時也能幫到別人!
參考文章: