關於像素,括號中爲別名
設備像素(物理像素)
DP(Device Pixel),顯示屏上的像素點,出廠即確定。
設備無關像素(設備獨立像素)
DIP(Device Independent Pixel),縮放比爲1時,設備獨立像素也等於CSS像素(邏輯像素)。我們通過CSS和javascript代碼設置的像素都是邏輯像素。在CSS規範中,長度單位可以分爲兩類,絕對(absolute)單位以及相對(relative)單位,px是一個相對單位,相對的是設備像素(device pixel)。顯示器上的小色框就是像素。
設備無關像素與CSS像素之間的關係 —— 頁面縮放比
頁面縮放比 = CSS像素/設備無關像素
設備像素與設備無關像素之間的關係 —— DPR
一般情況下,
設備像素比DPR = 設備像素/設備無關像素(在某一方向上,x方向或者y方向)
縮放比爲1時, 設備無關像素等於CSS像素,因此
設備像素比DPR = 設備像素/CSS像素(在某一方向上,x方向或者y方向)
縮放比爲1時,iphone4下dpr=2,iphone6 plus及以後dpr=3。
以iphone6爲例,iphone6的CSS像素爲375px*677px
,DPR是2,所以其設備像素爲750px*1354px
(x和y方向都乘了2)。
設備像素與CSS像素之間的關係
在PC端,CSS的1px往往等於一個設備像素。而在移動端,在不同的設備或不同的環境中,css中的1px所代表的設備物理像素是不同的。以iPhone爲例,iPhone4之前的手機,屏幕像素密度都較低,CSS的1px等於一個設備像素。但從iPhone4開始,喬布斯提出了Retina視網膜屏的概念。此時一個CSS像素等於(dpr*頁面縮放比)
個設備像素。
獲取DPR的方法
-
js獲取:
window.devicePixelRatio
。打開控制檯,輸入
window.devicePixelRatio
。就可以看到當前設備的DPR。切換手機視圖,再次輸入,可以看到模擬的手機視圖的DPR。
上圖中,第一個是PC端dpr,第二個是iPhoneX的dpr。 -
css媒體查詢:
min-device-pixel-ratio
關於視口
這部分內容中的圖借用一下思否中的一篇文章:關於移動端適配,你必須知道的
佈局視口(layout viewport)
佈局視口就是DOM的寬度。各瀏覽器默認的 layout viewport寬度一般都是800,980,1024等值。
js獲取
document.documentElement.clientWidth
document.documentElement.clientHeight
視覺視口(visual viewport)
視覺視口是可見視口,在PC端,瀏覽器窗口可以調整,視覺窗口等於整個瀏覽器的寬度,而在移動端,瀏覽器不能縮放,因此視覺視口即爲屏幕的寬度。
js獲取
window. innerWidth
window.innerHeight
理想視口(ideal viewport)
理想視口的概念常用於移動端,使用戶不需要縮放,也不需要出現橫向滾動條,便可以正常看到網站的所有內容。
理想視口下,佈局視口寬度 = 視覺視口寬度 = 設備寬度
由此也可以得到,
當前縮放值 = ideal viewport寬度 / visual viewport寬度
js獲取
screen.width
screen.height
設置理想視口
<meta name="viewport" content="width=device-width; initial-scale=1;">
關於initial-scale的默認值,安卓設備上沒有明確的定義。在iphone和ipad上,無論你給viewport設的寬度是多少,如果沒有指定默認的縮放值,則iphone和ipad會自動計算這個縮放值,以達到當前頁面不會出現橫向滾動條(或者說viewport的寬度就是屏幕的寬度)的目的。
比如在iPhone5下,不設置任何的viewport meta標籤時,layout viewport的默認寬度爲980px,但瀏覽器的visual viewport寬度爲320px,因此initial-scale = 320/890
,約爲0.327。
移動端適配解決方案
1. viewport(scale=1/dpr)
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
各個屬性的含義:
device-width
等於理想視口的寬度,設置width=device-width
就相當於讓佈局視口等於理想視口。
initial-scale = 理想視口寬度 / 視覺視口寬度
,設置initial-scale=1
就相當於讓視覺視口等於理想視口。
這時,1個CSS像素就等於1個設備獨立像素,而且我們也是基於理想視口來進行佈局的,所以呈現出來的頁面佈局在各種設備上都能大致相似。
2. rem
rem是css3新增的一個相對單位。rem爲相對HTML根元素的大小,除了IE8及更早的版本外,其他瀏覽器都支持rem。
阿里早期開源了一個移動端適配解決方案 —— flexible。通過這種方案,我們在頁面上統一使用rem佈局。
核心代碼:
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit();
上面的代碼中,將html節點的font-size設置爲頁面clientWidth(佈局視口)的1/10,即1rem就等於頁面佈局視口的1/10,這就意味着我們後面使用的rem都是按照頁面比例來計算的。
這樣我們只需要將設計稿的px轉成對應的rem即可。
在viewport和vw、vh存在兼容性問題的時候,阿里提出了這種解決方案。但是這種方案實際上是根據屏幕大小百分百還原設計稿,也就是說在屏幕大的設備上看到的元素會大一些,但是這個顯然不符合我們的需求。用戶使用更大的屏幕並不是爲了看到更大的字,而更多地是爲了看到更多的內容。
因此,這種方案最後被淘汰掉。
3. vm/vh
vh、vw方案即將視覺視口寬度 window.innerWidth 和視覺視口高度 window.innerHeight 等分爲 100 份。
這種方案和上面的方案解決問題的思路一樣。這個是需要將設計稿的px轉成對應的vw,當然這種比例關係我們不用手動計算,webpack解析css時有個postcss-px-to-viewport
插件,可以實現px到vw的自動轉化。
這種方案同樣存在上面提到的無法看更多內容的問題。另外,px轉換成vw不一定能完全整除,因此有一定的像素差。
4. flex
關於flex彈性佈局的用法可以參考阮一峯老師的這篇文章Flex 佈局教程:語法篇。在更大的屏幕上,flex佈局可以完美地爲用戶呈現更多內容。
移動端適配整體流程
- 在 head 設置 width=device-width 的 viewport‘
- 在 css 中使用 px
- 在適當的場景使用 flex 佈局,或者配合 vw 進行自適應
- 在跨設備類型的時候(pc <-> 手機 <-> 平板)使用媒體查詢
- 在跨設備類型如果交互差異太大的情況,考慮分開項目開發
1px問題及解決方案
1px問題
這裏的1像素指的是CSS像素。因此我們可以發現,在寫1px的時候,在不同dpr的物理設備上映射的設備像素是不同的。dpr爲2時,映射的像素爲2px;dpr3時就映射成3px。這樣的話,如果在屏幕尺寸比較大的設備上(準確來說時設備像素比較大),1px渲染出來就樣子就會有些粗。
解決方案
利用媒體查詢 + css3的transform
利用媒體查詢區分二倍屏和三倍屏,利用transform:scale(xx)
對高度進行縮放。代碼如下:
/*二倍屏*/
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.my-border::after {
transform: scaleY(0.5);
webkit-transform: scaleY(0.5);
}
}
/*三倍屏*/
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.my-border::after {
transform: scaleY(0.33);
webkit-transform: scaleY(0.33);
}
}
小數寫px(如0.5px)
IOS8下已經支持帶小數的px值,安卓與低版本IOS不適用。另外,各個瀏覽器對小數px的實現方式也不相同。
小知識
瀏覽器默認字體爲16px
瀏覽器最小字號12px
p代表的是縱向的像素數,1080p是指縱向有1080個像素
k代表的是橫向的像素數,2k屏是指橫向超過2048個像素的屏
參考鏈接
https://juejin.im/post/5e6caf55e51d4526ff026a71
https://segmentfault.com/a/1190000019207842#item-7-22
http://html-js.com/article/MobileWeb
https://www.jianshu.com/p/b13d811a6a76