移動端適配——>關於rem
目錄
為什麼要使用rem
之前有些適配做法,是通過js動態計算viewport的縮放值(initial-scale)。
例如以螢幕320畫素為基準,設定1,那螢幕375畫素就是375/320=1.18以此類推。
但直接這樣強制頁面縮放過於粗暴,會導致頁面圖片文字失真模糊。
Px是相對固定單位,字號大小直接被定死,所以使用者無法根據自己設定的瀏覽器字號而縮放,em和rem雖然都是相對單位,但em是相對於它的父元素的font-size,頁面層級越深,em的換算就越複雜,而rem是直接相對於根元素,這就避開了很多層級關係。移動端新型瀏覽器對rem的相容很好,可以放心使用。
通用換算和一些坑
有時我們會看到有些使用rem的頁面裡會先給頁面根元素一個樣式:
html {font-size: 62.5%; /*10 ÷ 16 × 100% = 62.5%*/}
為什麼是62.5%?
大多數瀏覽器的預設字號是16px,因此1rem=16px,這樣不方便我們px和rem的換算,假設1rem=10px,那麼100px=10rem,25px=0.25rem。這樣就好換算很多,於是就有了上面的10/16。
如果是640的設計稿,需要除以2轉化為和iphone5螢幕等寬的320。所以設計稿px單位/2/10轉為rem。之後再媒體查詢設定每個螢幕大小的font-size百分比,頁面會根據上面設定的根font-size適配。
看到這裡是不是覺得一切很完美?然而,這裡面有兩個深坑:
1.我看了網上很多關於rem的資料,基本都說瀏覽器的預設字號就是16px,然後直接定義font-size:62.5%。但是,rem屬於css3的屬性,有些瀏覽器的早期版本和一些國內瀏覽器的預設字號並不是16px,那麼上面的10/16換算就不成立,直接給html定義font-size: 62.5%不成立。
2.chrome強制字型最小值為12px,低於12px按12px處理,那上面的1rem=10px就變成1rem=12px,出現偏差(下面給demo)。
解決方案: 將1rem=10px換為1rem=100px(或者其它容易換算的比例值);不要在pc端使用rem。
那麼上面的頁面根元素樣式要改為:
html {font-size: 625%; /*100 ÷ 16 × 100% = 625%*/}
再用本工廠總結得出的各解析度媒體查詢換算:
@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
html { font-size: 703%; }
}
@media screen and (min-width:375px) and (max-width:383px) and (orientation:portrait) {
html { font-size: 732.4%; }
}
@media screen and (min-width:384px) and (max-width:399px) and (orientation:portrait) {
html { font-size: 750%; }
}
@media screen and (min-width:400px) and (max-width:413px) and (orientation:portrait) {
html { font-size: 781.25%; }
}
@media screen and (min-width:414px) and (max-width:431px) and (orientation:portrait){
html { font-size: 808.6%; }
}
@media screen and (min-width:432px) and (max-width:479px) and (orientation:portrait){
html { font-size: 843.75%; }
}
至此,坑填完。設計稿px換算直接/100即可得到rem值。
開始進入rem教程
1.先設定header裡面的meta標籤:
1 <meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
2.在header寫上<script>標籤
1 <script type="text/javascript"> 2 document.documentElement.style.fontSize = document.documentElement.clientWidth / 640*100 + 'px'; 3 </script>
問題:為什麼要設定Html的font-size?
答:這裡是設定html標籤的font-size,上面概論紅色字寫的很清晰,頁面元素使用rem單位時,是相對於這個html標籤的font-size的大小為基礎的。
問題:為什麼是clientWidth/640?為什麼要乘以100?
答:
1.是因為這裡是作為一個基礎數值,換個方向去想,這裡先不乘以100以免產生誤解。
例如:設計稿寬度是640px,有一個元素設計稿上的寬度是50px,裝置物理寬度是320px,那麼我們在頁面上應該設定寬度為 width:50rem,相當於寬度是:50*(320/640)=25px;這裡能正確算出在320px的裝置上剛好佔一半,其實可以想象為 rem=(320/640)。
2.一般瀏覽器的最小字型是12px,如果html的font-size=(320/640)px,相當於font-size=0.5px,那麼這個數值就小於12px,會造成一些計算的錯誤,和一些奇怪的問題,*100後,font-size是50px,就可以解決這種字型小於12px的問題。
3. 為了計算方便 我們後面把比率乘以了100,(320/640)*100,那麼相對應這個元素在設定數值的時候就需要除以100了(50/100),這樣可以保證最後出來的數值不變.
設定好html的font-size,那麼我們下面就可以開始編寫根據設計稿的例子了。
設計稿是640px,有一個紅色盒子寬高都是320px,裡面的文字是32px,那麼下面是這個例子的程式碼。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1, minimum-scale=1">
<script type="text/javascript">
document.documentElement.style.fontSize = document.documentElement.clientWidth / 640*100 + 'px';
</script>
</head>
<body style="margin: 0 ;padding: 0;font-size: 0.32rem">
<div style="width: 3.2rem;height: 3.2rem ;background: red">
<span>danny.xie</span>
</div>
</body>
</html>
1.在iphone5下的情況,裝置的物理畫素是320px
1.在iphone6下的情況,裝置的物理畫素是375px
可以看到字型的大小和紅色盒子的寬高跟設計稿上面的比例是保持一致的,這樣就是rem適配不同裝置的的基本用法