移動(dòng)端rem 適配方案

知識點(diǎn):

rem是什么?

rem(font size of the root element)是指相對于根元素的字體大小的單位。簡單的說它就是一個(gè)相對單位??吹絩em大家一定會想起em單位,em(font size of the element)是指相對于父元素的字體大小的單位。它們之間其實(shí)很相似,只不過一個(gè)計(jì)算的規(guī)則是依賴根元素(rem)一個(gè)是依賴父元素計(jì)算(em)。


個(gè)人理解rem布局可分為倆種情況無設(shè)計(jì)稿有設(shè)計(jì)稿

無設(shè)計(jì)稿

1、首先需要在<head>標(biāo)簽中加入

<meta name="viewport" content="width=device-width,initial-scale=1.0,maixmum-scale=1.0,minimum-scale=1.0,user-scalable=no">

對于viewport的詳細(xì)解釋可以參考這篇文章:https://www.cnblogs.com/2050/p/3877280.html

2、在<script>標(biāo)簽中加入

window.onresize = function(){
  document.documentElement.style.fontSize = document.documentElement.offsetWidth / 20 +'px';
}
/*
document.documentElement.style.fontSize 是得到<html>標(biāo)簽并為它設(shè)置font-size樣式字體大小,因?yàn)镽EM計(jì)算的規(guī)則是依賴根元素也就是<html>元素的字體大小
document.documentElement.offsetWidth  是獲取整個(gè)視口的寬度
*/

document.documentElement.offsetWidth / 20 這里的20不是固定的,這里 / 20 是把屏幕均分為20份,當(dāng)然也可使用16、18... , 但是這里有一個(gè)問題就是Chorme瀏覽器字體最小只能為12px,所以這里的最后結(jié)果(document.documentElement.offsetWidth / 20 = ?)最好別小于12。

3、嘗試讓一個(gè)div不管在什么屏幕下都占據(jù)一半,這里使用20均分所以這里div寬度只需要定位10rem就可以在任何屏幕下都占據(jù)一半。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>無設(shè)計(jì)稿rem</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maixmum-scale=1.0,user-scalable=no">
    <style>
        *{
            margin:0;
            padding:0;
        }
        html,body{
            width:100%;
            height:100%;
        }
    </style>
</head>
<body>
<div style="width:10rem;height:100%;background:#f22;">div</div>
<script>
    window.onresize = getRem;
    function getRem(){
        document.documentElement.style.fontSize = document.documentElement.offsetWidth / 20+'px';
    }
    getRem();
</script>
</body>
</html>
image.png
image.png
image.png
image.png

有計(jì)稿

以 iPhone5 和 iPhone7 舉例他們的屏幕分辨率是320px*568px,375px*667px
視覺設(shè)計(jì)師給的平面稿一般是 640px , 750px 寬度的設(shè)計(jì)稿
為什么設(shè)計(jì)稿會屏幕比例的倆倍呢?
這里引出一個(gè)知識點(diǎn):

dpr是什么?

window.devicePixelRatio是設(shè)備上物理像素和設(shè)備獨(dú)立像素(device-independent pixels (dips))的比例。
公式表示就是:window.devicePixelRatio = 物理像素 / dips
物理像素,比較好理解,一個(gè)物理像素是顯示器(手機(jī)屏幕)上最小的物理顯示單元,在操作系統(tǒng)的調(diào)度下,每一個(gè)設(shè)備像素都有自己的顏色值和亮度值。
dips,(dip或dp或device independent pixels)指的是設(shè)備獨(dú)立像素(也叫密度無關(guān)像素),可以認(rèn)為是計(jì)算機(jī)坐標(biāo)系統(tǒng)中得一個(gè)點(diǎn),這個(gè)點(diǎn)代表一個(gè)可以由程序使用的
詳細(xì)解釋:https://www.cnblogs.com/mtl-key/p/7126634.html

簡單的講其實(shí)就是dpr決定了css 1px 等于多少屏幕物理像素。

拿 iPhone6 和 普通PC機(jī) 舉例:
iPhone6的dpr等于2,也就是說如果你為一個(gè)div設(shè)置100px(這里100px是css像素)寬度,在iPhone6 屏幕上面div其實(shí)占據(jù)了200px物理像素(因?yàn)閕Phone 6 下 dpr=2)。而在普通pc屏幕下這個(gè)div占據(jù)的剛好是100px(因?yàn)閜c屏幕下dpr=1)

可以在Chorme移動(dòng)端DEBUG下開啟顯示dpr,也可以在console中打印window.devicePixelRatio查看

image.png
image.png

設(shè)計(jì)稿給的是 640px 的如下:


sc.jpg

實(shí)現(xiàn)rem布局:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>有設(shè)計(jì)稿rem</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maixmum-scale=1.0,user-scalable=no">
    <style>
        *{
            margin:0;
            padding:0;
        }
        html,body{
            width:100%;
            height:100%;
        }
    </style>
</head>
<body>
<div style="position:absolute;left:.94rem;top:1.63rem;width:1rem;height:1rem;background:#f00;"></div>
<div style="position:absolute;right:.94rem;top:1.63rem;width:1rem;height:1rem;background:#f00;"></div>
<div style="position:absolute;left:2.7rem;top:3.38rem;width:1rem;height:1rem;background:#00f;"></div>
<script>
    window.onresize = getRem;
    function getRem(){
        document.documentElement.style.fontSize = document.documentElement.offsetWidth / 6.4+'px';
    }
    getRem();
</script>
</body>
</html>

在任何設(shè)備下這三個(gè)div都會和設(shè)計(jì)稿一樣的布局展現(xiàn)。

 document.documentElement.offsetWidth / 6.4

這里 / 6.4是為了方便計(jì)算,當(dāng)然 / 80,/ 50...都行 , 前面提到過

有一個(gè)問題就是Chorme瀏覽器字體最小只能為12px,所以這里的最后結(jié)果最好別小于12。

所以這里讓設(shè)計(jì)稿寬度 / 100 之后

document.documentElement.offsetWidth / ( 640 / 100)
<div style="position:absolute;left:.94rem;top:1.63rem;width:1rem;height:1rem;background:#f00;"></div>
<div style="position:absolute;right:.94rem;top:1.63rem;width:1rem;height:1rem;background:#f00;"></div>
<div style="position:absolute;left:2.7rem;top:3.38rem;width:1rem;height:1rem;background:#00f;"></div>

div的單位只要跟隨 / 100 就行了,因?yàn)?/ 100 很好計(jì)算所以無需計(jì)算直接就能得出想要的rem大小。

相關(guān)問題:

<script>
    var d = window.document.createElement('div');
    d.style.width = '1rem';
    d.style.display = "none";
    var head = window.document.getElementsByTagName('head')[0];
    head.appendChild(d);
    //得到webview默認(rèn)字體大小
    var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width'));
    
    function getRem(){
        //計(jì)算方式不變,只需要在最后把單位轉(zhuǎn)換為百分比
        document.documentElement.style.fontSize = document.documentElement.offsetWidth / 6.4 / defaultFontSize * 100 + '%';
    }
    window.onresize = getRem;
    getRem();
</script>

以上示例均沒考慮兼容性問題,落實(shí)到項(xiàng)目上時(shí)切記自行補(bǔ)充兼容性代碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.meta 設(shè)置 因?yàn)檫@樣設(shè)置了,網(wǎng)頁寬度才和 設(shè)備寬度相同,才可以拿這個(gè)標(biāo)準(zhǔn)去限定范圍 瀏覽器默認(rèn)的viewp...
    xuefeilvye閱讀 729評論 0 10
  • 1.meta 設(shè)置 因?yàn)檫@樣設(shè)置了,網(wǎng)頁寬度才和 設(shè)備寬度相同,才可以拿這個(gè)標(biāo)準(zhǔn)去限定范圍瀏覽器默認(rèn)的viewpo...
    xuefeilvye閱讀 1,318評論 0 0
  • 移動(dòng)端適配方案:1)viewport(scale=1/dpr)2)rem3)flex4)vm/vh一、什么是移動(dòng)端...
    puxiaotaoc閱讀 43,345評論 3 56
  • 1.安裝hotcss cnpm install hotcss -S 2.引入hotcss.js到頁面 3.引入px...
    famingng閱讀 1,040評論 0 1
  • 到達(dá)親愛的佛山,有玫瑰花的驚喜,另外吃了好多次酒店隔壁的粥和花蛤。
    流景景閱讀 232評論 0 0

友情鏈接更多精彩內(nèi)容