涉及到的一些名詞, 詳細解釋可參考 移動端適配前篇--移動端適配 remcss
【英寸Inch】英寸表示屏幕斜對角線的長度
【像素Pixel】像素是圖像的基本採樣單位,它不是一個肯定的物理量,由於像素點的物理大小是不肯定的
【分辨率】分辨率是屏幕像素的數量,通常用屏幕寬度的像素點乘以屏幕高度的像素點。如描述iphone6的分辨率是750*1334
.
分辨率又分爲【物理分辨率】和【邏輯分辨率】,值得注意的是實際工做中設計師經常給的是物理分辨率,程序中用到的是邏輯分辨率,可是都稱爲分辨率,容易混淆。
【物理分辨率】是硬件所支持的分辨率,【邏輯分辨率】是軟件能夠達到的分辨率。
【像素倍率dpr】物理分辨率和邏輯分辨率的商,即常說的幾倍屏。html
如:iphone6的分辨率寫着375*667
,指的是邏輯分辨率;750*1334
則是它的物理分辨率,dpr=2。前端
使用rem適配,目前最流行的兩種方式:分別是網易和手淘的作法git
設備邏輯像素 device-width = 設備物理像素 /(devicePixelRatio * scale)
設備物理像素: iphone6 = 750px
設備邏輯像素: iphone6 = 750/(2 * 1) = 375px
document.documentElement.clientWidth === 設備邏輯像素
body-width(rem爲單位) = 設計稿寬度/100 = 640 / 100 = 6.4 rem 【取100,主要爲了容易計算】
html font-size(px爲單位) = device-width / body-width = 320 / 6.4 = 50 pxgithub
【步驟】
(1)視口設置:<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, minimum-scale=1">
(2)先拿設計稿豎着的橫向分辨率除以100獲得body元素的寬度:
若是設計稿基於iphone6,橫向分辨率爲750,body的width爲750 / 100 = 7.5rem
若是設計稿基於iphone4/5,橫向分辨率爲640,body的width爲640 / 100 = 6.4rem
(3)佈局時,設計圖標註的尺寸除以100獲得css中的尺寸
設計稿150px的寬度,代碼爲 150/100 rem
(4)在dom ready之後,經過如下代碼設置html的font-size:
document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
【html的font-size的值 是根據設備改變而改變的】
(注:6.4是設計稿基於iphone4/5,若是是750的設計稿,應該除以7.5)
(5)font-size可能須要額外的媒介查詢,而且font-size不能使用rem【此處的px是指設備邏輯像素】segmentfault
@media screen and (max-width:321px){ .m-navlist{font-size:15px} } @media screen and (min-width:321px) and (max-width:400px){ .m-navlist{font-size:16px} } @media screen and (min-width:400px){ .m-navlist{font-size:18px} }
【注意】最大寬度限制 設備邏輯像素寬度640 =》設備物理像素寬度1280 至關於pc端
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px'; 【此處6.4,因爲網易以iPhone4/5,物理像素爲640 * 1136
】dom
前提:假如以iPhone6/7/8爲設計稿,寬度爲150的元素 在 iphone6/7/8中: 因爲【dpr = 2】,該元素的邏輯像素 = 150 / 2 = 75 px html-fontSize = 375 / 7.5 = 50 px 該元素的 width = 150 / 100 = 1.5 rem 該元素的邏輯像素 / html-fontSize = 75 / 50 = 1.5 在iPhone4/5中:【逆推】 在 iphone4/5中,html-fontSize = 320 / 7.5 = 42.67 px 該元素的 width = 1.5 rem 該元素的邏輯像素 = html-fontSize * 該元素的 width(rem) = 42.67 * 1.5 = 64 px 因爲【dpr = 2】,該元素的物理像素 = 邏輯像素 * dpr = 64 * 2 = 128 (即該元素的寬爲128) 該元素的邏輯像素 / html-fontSize = 64 / 42.67 = 1.5 **總結: 64/320 = 75/375 = 0.2 至關於百分比適配,該元素佔整屏寬度的20%**
demo:iphone
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>移動端適配</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/> <style> /* vw + rem */ html{font-size:13.33333333vw} .box { width: 1.5rem; height: 1.5rem; background-color: #ccc; font-size: 0.24rem; } /* rem 網易*/ .box { width: 1.5rem; height: 1.5rem; background-color: #ccc; font-size: 14px; } /*邏輯像素*/ @media screen and (max-width:321px){ .box{font-size:15px} } @media screen and (min-width:321px) and (max-width:400px){ .box{font-size:16px} } @media screen and (min-width:400px){ .box{font-size:18px} } </style> <script> window.onload = function () { var deviceWidth = document.documentElement.clientWidth; if(deviceWidth > 640) deviceWidth = 640; document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px'; } </script> </head> <body> <div class="box"> oooo </div> </body> </html>
(1)動態設置viewport的scale佈局
var scale = 1 / devicePixelRatio; document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
(2)動態計算html的font-sizeflex
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
(3)佈局的時候,各元素的css尺寸 = 設計稿標註尺寸/(設計稿橫向分辨率 / 10)
(4)font-size可能須要額外的媒介查詢,而且font-size不使用rem,這一點跟網易是同樣的。
總結:
設備邏輯像素 device-width = 設備物理像素 /(devicePixelRatio * scale) 因爲 scale = 1 / devicePixelRatio,因此【設備邏輯像素 = 設備物理像素】
前提:假如以iPhone6/7/8爲設計稿,寬度爲150的元素 在 iphone6/7/8中: 設備邏輯像素 = 750 /(`2*0.5`) = 750 px 因爲【dpr = 2】,該元素的邏輯像素 = 150 /(`2*0.5`) = 150 px html-fontSize = 750 / 10 = 75 px 該元素的 width(rem) = 150 / html-fontSize = 150 / 75 = 2 rem 在iPhone4/5中:【逆推】 在 iphone4/5中,html-fontSize = 640 / 10 = 64 px 該元素的 width = 2 rem 該元素的邏輯像素 = html-fontSize * 該元素的 width(rem) = 64 * 2 = 128 px => 150 / 750 = 128 / 640 = 0.2
var scale = 1 / devicePixelRatio; document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
demo:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>移動端適配</title> <!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/> --> <meta name="viewport"/> <style> .box { width: 2rem; height: 2rem; background-color: #ccc; font-size: 14px; } /*邏輯像素*/ @media screen and (max-width:321px){ .box{font-size:15px} } @media screen and (min-width:321px) and (max-width:400px){ .box{font-size:16px} } @media screen and (min-width:400px){ .box{font-size:18px} } </style> <script> window.onload = function () { var scale = 1 / devicePixelRatio; document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); // console.log(document.documentElement.clientWidth) // 750 = 750 / (2 * 0.5) // 設備邏輯像素 device-width = 設備物理像素 /(devicePixelRatio * scale) document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px'; } </script> </head> <body> <div class="box"> oooo </div> </body> </html>
html{font-size:13.33333333vw} <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
1vw表示1%的屏幕寬度, 即屏幕寬度被分爲100份vw
width:1rem 的div 就是50px* 50px (iphone6爲2倍屏,即對應750px設計稿上的100px*100px)
7.5 rem = 100vw = 750px 設計稿 =》1px = 0.1333333vw =》 100px = 13.33333vw => 100px = 1rem
以iPhone6/7/8爲設計稿標準, 寬度爲 180 px
該元素的寬度(rem)= 180 / 100 = 1.8 rem
佈局時各元素的尺寸值都是根據設計稿標註的尺寸計算出來,因爲html的font-size是動態調整的,因此可以作到不一樣分辨率下頁面佈局呈現等比變化
通過正反推算,發現各類單位適配本質上對應着仍是根據手機屏幕尺寸基於百分比
進行縮放
參考:
最簡單的移動端適配方案(rem+vw)
移動端(手機端)頁面自適應解決方案—rem佈局
移動前端自適應適配佈局解決方案和比較