動態rem與1px邊框問題的理解


當我們在項目開發中,拿到設計師的設計圖,滿懷欣喜的准備按照設計圖將頁面實現出來的時候,我們通常會遇到這個問題:

如何將頁面的內容按照在不同手機屏幕瀏覽的情況下,比例都是不變的呢?這個時候我們就需要使用到動態rem來解決問題。

1:拿到屏幕寬度,以屏幕寬度作為rem的基准值

2:如果覺得基准值過大,將px換算成rem比較麻煩,可以將基准值縮小10倍

3:因谷歌瀏覽器有一個最小字體值,所以基准值不要低於這個最小字體值(12px)。

4:將rem賦值給html

var width = window.screen.width 
var fontSize = width/10 + 'px'
document.getElementsByTagName('html')[0].style.fontSize = fontSize

  

當我們在寫頁面的時候設計師會提出這樣一個要求:頁面不管怎么縮放都可以,但是1px的邊框必須給我是1px,不能縮放。我們會覺得這個問題很奇葩,心里想大不了直接給border:1px不就行了。可這個時候設計師又會說:我要的是手機上的實際像素1px!!!

真是有句mmp不知當講不當講。

好,既然需求說了,我們總不能說勞資不干了吧。那這個時候就需要了解到這個知識點:何為retina屏幕?啥是dpr?靈魂畫師上圖說話:

           

我們可以發現,在同樣的大小下,2dpr的屏幕時普通屏幕像素點的4倍,3dpr的屏幕時普通屏幕像素點的9倍。這就是retina屏幕用了都說好的原因(清晰)。而設計師要的實際1px的邊框就是下面這種情況:

         

這下我們終於明白設計師要的是啥效果了,那我們怎么解決呢?

思路:我們將border設置為1px,然后將也頁面的整體根據頁面的dpr縮小相應的倍數,接着將rem補償相應的倍數,這樣頁面中只有1px的邊框縮小了,而其他內容經過縮小和擴大,還是原來的狀態。

1:獲取dpr的值:

var dpr = window.devicePixelRatio

2:頁面縮放相應的倍數:

注意:頁面中<meta name="viewport"......只能作用一次,所以只能用js插入。記住content="width=device-width"千萬不要加,不然就不會縮放了(因為這句話的意思是寬度等與設備寬度)

var scale = 1/dpr
var metaEle = document.getElementById("meta")
metaEle.setAttribute("content",'user-scalable=no, initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale)

 

最后我們全部代碼貼上:

var width = window.screen.width 
var dpr = window.devicePixelRatio
var scale = 1/dpr
var fontSize = width/10*dpr + 'px'
document.getElementsByTagName('html')[0].style.fontSize = fontSize
var metaEle = document.getElementById("metaEle")   //這個是meta元素
metaEle.setAttribute("content",'user-scalable=no, initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale) 

  

這樣,我們就可以將頁面中需要加寬高的元素,換算成rem就行啦。  

如:iphone5中,1rem = 64px;那我們頁面中某個寬高為128px和64px的元素需,設置為width=2rem;height=1rem就可以啦。

 

 

2017/9/18更新:

在閱讀大漠老師的文章后,發現這個之前的方法還是有不足之處(僅作用於dpr為整數,並且viewport為360,720或1080),所以將代碼改為如下方式,其具體代表的意思請參考:傳送門

metaEl.setAttribute('content', 'target-densitydpi=device-dpi,user-scalable=no,initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale);
//不通過加入具體設備的白名單,通過此特征檢測 docEl.clientWidth == 980 //initial-scale=1不能省,因為上面設置為其他的scale了,需要重置回來
if(docEl.clientWidth == 980) {
   metaEl.setAttribute('content', 'target-densitydpi=device-dpi,width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1');
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM