前言:正好最近有時(shí)間,給移動(dòng)端適配這里做一個(gè)整理,全面并且深入地重新去理解這些代碼的含義,不再只是代碼的搬運(yùn)工,不再只會(huì)像之前一樣復(fù)制粘貼,這篇rem和em是因?yàn)槲易约鹤隽撕脦讉€(gè)移動(dòng)端的rem了,都是組長算好告訴比率什么的直接用就行了,對(duì)于rem和em到底是個(gè)什么東西還是完全沒有頭緒的,所以上網(wǎng)查了一些資料,整理出這篇文章。如果覺得對(duì)你有幫助,麻煩點(diǎn)個(gè)贊~~
關(guān)鍵詞:移動(dòng)端適配,rem,em~~......
正文:
一、基本定義
??rem,官方定義就是根據(jù)網(wǎng)頁的根元素來設(shè)置字體大小。那也就是說,一旦網(wǎng)頁的根元素的大小發(fā)生了變化,那rem也會(huì)相應(yīng)的變化,以rem為單位的也會(huì)成比例放大或縮小。那不就是等價(jià)于可以適應(yīng)我們各種手機(jī)屏幕嗎?
二、rem和px互相轉(zhuǎn)化
??現(xiàn)在大部分瀏覽器IE9+,F(xiàn)irefox、Chrome、Safari、Opera ,如果我們不修改相關(guān)的字體配置,都是默認(rèn)顯示font-size是16px.。那既然rem就是根據(jù)網(wǎng)頁的根元素來設(shè)置字體大小,那么如果我們想給一個(gè)div標(biāo)簽設(shè)置12px的字體大小那么用rem來寫就是:
html {
font-size:16px;
}
div {
font-size: 0.75rem; //12÷16=0.75(rem)
}
??就是16px代表著1rem,那12px是多少rem呢?就是12÷16=0.75rem。那么,當(dāng)網(wǎng)頁根元素字體改變時(shí),我們以rem為單位的標(biāo)簽們會(huì)發(fā)生什么樣的變化?舉個(gè)栗子:
.box{
width: 10rem;
height: 10rem;
background: red;
}
<div class="box"></div>
//默認(rèn)情況下

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

三、在工作中的應(yīng)用-----寫js(萬能的js)
??那我們?cè)鯓影阉鼞?yīng)用到我們的實(shí)際工作中去呢?大家都了解,在實(shí)際工作中,我們要面對(duì)各式各樣的手機(jī)型號(hào),他們的大小都不一樣。但是我們收到的psd設(shè)計(jì)稿,往往只有一張。一般我們獲取到的設(shè)計(jì)稿大部分是iphone6的,也就是最為常見的寬為750像素的設(shè)計(jì)稿。(事實(shí)上是我遇到的都是750像素的設(shè)計(jì)稿)而iPhone6的可視區(qū)在320px左右,所以在使用rem之前,我們一般會(huì)自覺的將所量出的寬高除以2。
??既然rem是根據(jù)HTML根元素的fontsize大小來計(jì)算變化的,那我們就把根元素的fontsize設(shè)置為一個(gè)變量,這個(gè)變量根據(jù)移動(dòng)端可視區(qū)寬度的變化而變化。
最初的做法是這樣的:
document .getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
這里為什么要除以10呢,其實(shí)這個(gè)值是隨便定義的,因?yàn)椴幌胱宧tml的font-size太大??墒怯袥]有發(fā)現(xiàn)如果這樣計(jì)算的話,我們按照的設(shè)計(jì)稿的像素來制作還是會(huì)有出入的。所以,就接下來有了這個(gè)辦法:
var baseWidth = 750,
baseFontSize = 100;
document .getElementsByTagName('html')[0].style.fontSize = window.innerWidth / baseWidth * baseFontSize + 'px';
看懂了嗎,沒看懂的我來解釋一下,看懂的就跳過。
我們現(xiàn)在有一個(gè)標(biāo)準(zhǔn),就是設(shè)計(jì)稿。寬為750px,我們?cè)O(shè)根元素HTML的font-size為100px,這以便于后續(xù)測(cè)量后好計(jì)算,而事實(shí)上,很多都是以100為標(biāo)準(zhǔn)的。
現(xiàn),我們有,標(biāo)準(zhǔn)版width750px,html{font-size:100px;},一部不知名手機(jī),width = window.innerWidth,那么,現(xiàn)在有個(gè)問題,這個(gè)不知名的手機(jī)的HTML里面的font-size相應(yīng)為多少?很簡單的一道數(shù)學(xué)題。
750 width
100px ?
? = width/750 *100 ??????width/750其實(shí)就是該不知規(guī)格的手機(jī)與標(biāo)準(zhǔn)的比率。也就是說,標(biāo)準(zhǔn)的100px,對(duì)應(yīng)了實(shí)用手機(jī)的1rem。那在psd中,我們所測(cè)量的所有的寬高長度,只要除以100,都是實(shí)際我們寫在css里的以rem為單位的長寬高。
最后,讓我們完善它:
<head>
<script type="text/javascript">
/*動(dòng)態(tài)調(diào)整rem值,除以100*/
function setsize() {
var winW = document.documentElement.clientWidth,
winH = document.documentElement.clientHeight,
baseFontSize = 100,
baseWidth = 750,
winWidthSize = Math.min(winW, winH);
if (winWidthSize < 270) {
winWidthSize = 270;
}
var _html = document.getElementsByTagName('html')[0];
_html.style.fontSize =winWidthSize / baseWidth * baseFontSize + 'px';
}
setsize();
</script>
</head>
切記:既然是JS代碼,為了避免造成因?yàn)閯?dòng)態(tài)設(shè)置<html>元素的font-size而造成頁面抖動(dòng),一般這部分代碼我們放在header底部去加載,并內(nèi)聯(lián)到html文檔里面。
四、這里收錄一個(gè)從博客里面看到的方法:
我們知道,一般我們獲取到的視覺稿大部分是iphone6的,所以我們看到的尺寸一般是雙倍大小的,在使用rem之前,我們一般會(huì)自覺的將標(biāo)注/2,其實(shí)這也并無道理,但是當(dāng)我們配合rem使用時(shí),完全可以按照視覺稿上的尺寸來設(shè)置。
1 設(shè)計(jì)給的稿子雙倍的原因是iphone6這種屏幕屬于高清屏,也即是設(shè)備像素比(device pixel ratio)dpr比較大,所以顯示的像素較為清晰。
2 一般手機(jī)的dpr是1,iphone4,iphone5這種高清屏是2,iphone6s plus這種高清屏是3,可以通過js的window.devicePixelRatio獲取到當(dāng)前設(shè)備的dpr,所以iphone6給的視覺稿大小是(*2)750×1334了。
3 拿到了dpr之后,我們就可以在viewport meta頭里,取消讓瀏覽器自動(dòng)縮放頁面,而自己去設(shè)置viewport的content例如(這里之所以要設(shè)置viewport是因?yàn)槲覀円獙?shí)現(xiàn)border1px的效果,加入我給border設(shè)置了1px,在scale的影響下,高清屏中就會(huì)顯示成0.5px的效果)
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');
4 設(shè)置完之后配合rem,修改
@function px2rem($px){
$rem : 75px;
@return ($px/$rem) + rem;
}
雙倍75,這樣就可以完全按照視覺稿上的尺寸來了。不用在/2了,這樣做的好處是:
1 解決了圖片高清問題。
2 解決了border 1px問題(我們?cè)O(shè)置的1px,在iphone上,由于viewport的scale是0.5,所以就自然縮放成0.5px)
在iphone6下的例子:
我們使用動(dòng)態(tài)設(shè)置viewport,在iphone6下,scale會(huì)被設(shè)置成1/2即0.5,其他手機(jī)是1/1即1.
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');
我們的css代碼,注意這里設(shè)置了1px的邊框
.con {
margin-top: 200px;
width: 5.3rem;
height: 5.3rem;
border-top:1px solid #000;
}
參考資料:移動(dòng)web適配利器-rem:http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem/