這個是瀏覽器使用的抽象單位,用來精確度量網頁上的內容。平時常常寫的width:100px;height:100px;都是與設備無關的。css
meta裏面設置width=device-width,這個device-width就是設備獨立像素android
在chrome裏 看到的ip6爲375667,ip4爲320480等等都是設備獨立像素,它們在數值上與css數值是相等的。web
是顯示屏的最小物理單位,每一像素都包含本身的顏色、亮度。像素是沒有大小的、是一個抽象概念、是一個相對單位。 關於像素有一個常見的錯誤理解:認爲像素是一個寬高相等的小方塊,而且的像素都是「那麼大」,可是不知道這個寬高的具體數字。chrome
泛指量測或顯示系統對細節的分辨能力。以ip6手機屏幕爲例,分辨率爲750×1334,這是指屏幕縱向能顯示1920個像素,橫向能顯示1080個像素瀏覽器
設備像素比(簡稱dpr)定義了物理像素和設備獨立像素的對應關係,它的值能夠按以下的公式的獲得:
設備像素比 = 物理像素 / 設備獨立像素 // 在某一方向上,x方向或者y方向app
好處:爲了寬屏顯示更多內容iphone
平常的 h5 項目使用 viewport 的 initail-scale 爲 1,寬度設置配合百分比佈局,1px 問題使用 transform 方案會最方便。因爲每種設備的設備獨立像素不一樣,最終效果也不一樣,最後的視覺效果以下:佈局
問題:若是設計稿中給的是某邊框線是 1px,那麼按照上述規則,就得設置這個邊框爲 0.5px,可是部分機型不會支持小數點的 px 尺寸。字體
爲了獲得極細緻的真實 1px 單位的邊框,衍生出了不少的解決辦法,使用的比較多的有兩種解決方案。其一爲 transform 縮放,其二爲動態 viewport。scala
transfrom 方案,能夠搭配僞元素來使用,若是隻是爲了獲得底邊的話,那麼設置爲高度 1px,而後縮放 y 軸爲 0.5。
.scale { position: relative; } .scale:after { content: ""; position: absolute; bottom: 0px; left: 0px; right: 0px; border-bottom: 1px solid #ddd; -webkit-transform: scaleY(.5); transform: scaleY(.5); -webkit-transform-origin :0 0; transform-origin :0 0; }
若是須要設置四邊的話,則這麼設置
.scale:after{ content: ""; pointer-events: none; /* 防止點擊觸發 */ box-sizing: border-box; position: absolute; width: 200%; height: 200%; left: 0; top: 0; border-radius: 8px; border:1px solid #999; -webkit-transform: scale(.5); transform: scale(.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; }
若是是電商的活動頁這種對視覺效果比較嚴謹的,則使用rem和動態viewport方案,最終的視覺效果以下:
源碼以下面,基礎思想就是設置根節點元素上得font-size,使之爲十六分之一屏幕寬度(相似柵格系統,淘寶爲1/10分屏寬,貝貝1/16屏寬)。在設置viewport爲1/drp的值就能夠了。
;(function(win) { var h; var dpr = win.navigator.appVersion.match(/iphone/gi)?win.devicePixelRatio:1; var scale = 1 / dpr; var docEl = document.documentElement; var metaEl = document.createElement('meta'); function setUnitA(){ win.rem = docEl.getBoundingClientRect().width / 16; docEl.style.fontSize = win.rem + 'px'; } win.dpr = dpr; win.addEventListener('resize', function() { clearTimeout(h); h = setTimeout(setUnitA, 300); }, false); win.addEventListener('pageshow', function(e) { if (e.persisted) { clearTimeout(h); h = setTimeout(setUnitA, 300); } }, false); docEl.setAttribute('data-dpr', dpr); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = document.createElement('div'); wrap.appendChild(metaEl); document.write(wrap.innerHTML); } setUnitA(); })(window);
iPhone6計算出的根節點元素的font-size爲__750px/16=46.876px__,那麼跟着設計稿的尺寸,css單位應該這麼寫:css寫的尺寸(單位爲rem) = 設計稿裏的元素尺寸 / 46.875。這種方案,頁面上使用了rem單位的元素在不一樣倍率手機下css尺寸都不一樣,例如在iphone5裏,css尺寸就是__設計稿元素尺寸 / 46.875 * 40。
然而事情尚未完,若是設計師但願能讓大屏的狀況顯示更多的字,而非把字給這樣放大了,那麼字體則不能使用rem爲單位。看下面的一段代碼
.px2px(@name, @px){ @{name}: round(@px / 2) * 1px; [data-dpr="2"] & { @{name}: @px * 1px; } // for mx3 [data-dpr="2.5"] & { @{name}: round(@px * 2.5 / 2) * 1px; } // for 小米note [data-dpr="2.75"] & { @{name}: round(@px * 2.75 / 2) * 1px; } [data-dpr="3"] & { @{name}: round(@px / 2 * 3) * 1px } // for 三星note4 [data-dpr="4"] & { @{name}: @px * 2px; } } .fontSize(@px) { .px2px(font-size, @px); }
用法爲.fontSize(設計稿裏此元素的字體大小) ;
,這樣就能獲得不一樣倍率下正確的字體大小,不過此法仍然有一個問題,須要窮舉出全部的dpr狀況,android機子碎片化很是嚴重,因此總會有一些奇奇怪怪的機型效果不如意。