說明:動態(tài)REM是移動端專用的自適應方案群扶,需要注意的是,它并不屬于響應式布局,不支持在PC上使用該方案竞阐。
一缴饭、em和rem分別是什么
em和rem都是眾多長度單位的中的一種,MDN給出的定義分別是
em是一個相對長度單位骆莹,這個單位表示元素的
font-size
的計算值颗搂。如果用在font-size
屬性本身,它會繼承父元素的font-size幕垦。
rem代表根元素的
font-size
大卸狻(例如<html>
元素的font-size)。當用在根元素的font-size
上面時 先改,它代表了它的初始值疚察。
其他的長度單位還有px(像素)、vw(100vw == 視口寬度)仇奶、vh(100vh == 視口高度)等等貌嫡。
注意:
- chrome默認font-size大小為16px
- chrome默認最小字號為12px(可在設置中更改),這意味著即使設置font-size<12px该溯,打開控制臺查看計算出來的font-size依舊是12px
二衅枫、移動端的特點
打開開發(fā)者工具切換到手機端,我們發(fā)現所有手機顯示的界面都大同小異朗伶,不同的僅僅只是屏幕的大小(寬高)
機型 | 大小 |
---|---|
iPhone 4 | 320 x 480 |
iPhone 5/SE | 320 x 568 |
iPhone 6/7/8 | 375 x 667 |
iPhone 6/7/8 Plus | 414 x 736 |
iPhone X | 375 x 812 |
三步咪、移動端適配方案
方案一:媒體查詢
從上面可以看出论皆,光是iPhone這一類手機就有如此多不同的寬高,更別說要適配所有手機了猾漫,顯然這時候如果使用媒體查詢來做適配不可鹊闱纭(那得寫n多套樣式)
方案二:百分比布局
思路:不用定寬/定高,而是將寬高都設置為百分比悯周,這樣不管屏幕大小如何變化粒督,總是保持最初的比例不變
我們可以發(fā)現禽翼,元素寬度隨屏幕寬度變化而變化屠橄。但問題是,元素高度沒辦法與屏幕寬度相關聯(lián)闰挡,比如這里我們想讓高度為寬度的一半就無法做到锐墙,這樣就無法保持原始的比例,如果是圖片的話會發(fā)生明顯的形變长酗。
解決方法:去掉高度溪北,使用padding
將元素撐起來
width: 40%; /* 屏幕寬度的40% */
height 0;
padding-bottom: 20%; /* 屏幕寬度的20% */
這樣就用百分比布局做到了實現寬高都自適應的效果
代碼:http://js.jirengu.com/peziq/3/edit?html,css,output
當然,為了引入我們的主題,這里還介紹另外一種方法動態(tài)REM之拨。
四茉继、動態(tài)rem(JS動態(tài)地調整rem)
從上面對百分比布局的分析中,我們不難發(fā)現蚀乔,只需要把元素的寬高與屏幕寬度關聯(lián)起來烁竭,就可以實現根據屏幕寬度來進行縮放。
換個思路乙墙,我們不使用百分比布局颖变,而是改為固定寬高,讓元素寬高兩者都有的長度單位和手機屏幕寬度進行關聯(lián)听想。
但是無論是px腥刹、em還是rem都與手機屏幕的寬度無關(vw與屏幕寬度有關,但這個屬性的兼容性太差汉买,這里我們不使用它)
將rem與手機屏幕寬度進行關聯(lián)
雖然除vw之外的長度單位都與屏幕寬度無關衔峰,但是1rem == html的font-size
啊,這樣我們只需要讓font-size == 屏幕寬度
(用JS做)蛙粘,即1rem == html的font-size == 屏幕寬度
垫卤,這樣就把長度單位rem與手機屏幕寬度關聯(lián)起來了。
1 rem == html font-size == viewport width
我們用JS來實現font-size == 屏幕寬度
var pageWidth = window.innerWidth
document.write('<style>html{font-size:'+pageWidth+'px;}</style>')
效果如下:
每次運行JS都會改變rem的值出牧,即JS動態(tài)地調整rem穴肘,這就是動態(tài)rem。
五舔痕、對rem進行微調
- 別忘了移動端得加一個meta viewport评抚,加了之后才能正常顯示出動態(tài)rem的效果
- 不一定非得讓rem和屏幕寬度保持1:1
比如,上例中我們可以讓1 rem == html font-size == viewport width/10
伯复,
即1 rem == 0.1 width
document.write('<style>html{font-size:'+pageWidth/10+'px;}</style>')
這樣我們在寫寬高的時候就不用總是寫小數了慨代,便于我們取整數
不過需要注意的是,不要把比例設置得太小啸如,否則會出bug侍匙。
比如你設置1 rem == 0.01width
,因為在chrome中叮雳,默認最小字號為12px想暗,當屏幕寬度為375px時碉输,此時html的font-size為3.75<12取逾,字體大小變化是不會生效的,瀏覽器依然按照最小的12px來計算职辅。
-
REM 可以與其他單位同時存在
當計算出來的rem值特別小時就別用rem值了厌均,比如上例中唬滑,如果此時
我要為元素添加border,通過計算1px/640 == 0.0015 == 0.015 rem,
這樣計算出來的rem值太小時晶密,border就會顯示不精確擒悬。因此,當rem值太小時稻艰,可以不使用rem懂牧,rem可以與其他長度單位混用。
六尊勿、讓px自動變?yōu)閞em
每次都要計算rem值比較麻煩僧凤,我們可以通過SCSS將px直接翻譯為正確的rem值。
使用步驟如下:
- npm config set registry https://registry.npm.taobao.org/
- touch ~/.bashrc
- echo 'export SASS_BINARY_SITE="https://npm.taobao.org/mirrors/node-sass"' >> ~/.bashrc
- source ~/.bashrc
- npm i -g node-sass
- mkdir ~/Desktop/scss-demo
- cd ~/Desktop/scss-demo
- mkdir scss css
- touch scss/style.scss
在scss文件中添加以下內容
$ cat scss/style.scss @function px($px) {
@return $px/$designWidth*10 + rem;
}
$designWidth: 400px; // 400px是設計稿的寬度元扔,你要根據設計稿的寬度填寫
.child {
width: px(160px);
height: px(80px);
margin: px(20px) px(20px);
border: 1px solid red;
float: left;
font-size: 16px;
}
- node-sass -wr scss -o css