移動端rem.js適配螢幕
九月已成歷史,十月如期而至...可能是九月工作比較清閒,週記就沒怎麼寫,十月決不能這麼墮落,立貼為證,至少保證5篇部落格!!!如果沒學到什麼新知識,就對以往的那些工作中常用到的知識點做個總結...話不多說,今天就來談談移動端的rem適配...本文將從rem是什麼、為什麼要用rem適配、怎麼用rem來講解,保證淺顯易懂...
1、什麼是rem
rem(font size of the root element)是指相對於根元素(<html> )的字型大小的單位。簡單的說它就是一個相對單位。看到rem大家一定會想起em單位,em(font size of the element)是指相對於自身的字型大小 的單位。它們之間其實很相似,只不過一個計算的規則是依賴根元素一個是依賴父元素計算。
2、為什麼用rem適配
由於移動端的螢幕眾多,就拿iphone來說,iphone5、iphone6、iphone6+分別是360px、375px、414px...Android機的解析度更是百花齊放...面對這麼多的螢幕,px顯然不能輕易去適配了,比如設定div的
padding-left為10px時,iphone5中比例和設計稿一致,但iphone6+則顯得有點“瘦”了,因此我們要想著去適配不同螢幕的手機,讓設計稿在解析度相差很大的手機上顯示的效果也要一樣。
早期的適配用百分比+媒介查詢寫很多型別的css程式碼,這時候的程式碼量很大,適配效果也不是很好,畢竟機型太多...這時候rem的優勢就充分展示出來了...不同解析度的螢幕,通過動態設定rem的值(即根元素的字型大小),就能實現等比例縮放的效果。
3、怎麼用rem
計算rem的方式大致分為兩種:手淘的flexible和網易的rem.js (都是早期用法,現在已改版);還有一種不用js計算,使用vw單位,一行css程式碼搞定;
網易與手淘方案:
1)、網易:
第一:設定視口
<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
第二:在dom ready以後,通過以下程式碼設定html的font-size:
var deviceWidth = document.documentElement.clientWidth; if(deviceWidth > 640) deviceWidth = 640; document.documentElement.style.fontSize = deviceWidth / 6.4 + ‘px‘;// 6.4是根據設計稿/100 算出來的 具體值由設計稿定
目前小米的官網就是這種:
!function(n){ vare=n.document, t=e.documentElement, i=720, d=i/100, o="orientationchange"in n?"orientationchange":"resize", a=function(){ var n=t.clientWidth||320;n>720&&(n=720);// 720的設計稿 t.style.fontSize=n/d+"px" }; e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1)) }(window);
2)、手淘:
第一、判斷head中是否設定了viewport,如果有設定,按照已有viewport 設定縮放比
if (metaEl) { console.warn('將根據已有的meta標籤來設定縮放比例'); var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/); if (match) { scale = parseFloat(match[1]); dpr = parseInt(1 / scale); } }
第二、如果沒有設定meta viewport,判斷是否設定dpr,如果有,通過dpr計算縮放scale
var content = flexibleEl.getAttribute('content'); if (content) { var initialDpr = content.match(/initial\-dpr=([\d\.]+)/); var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);//maximum 設定最大值,與initial的值比較,取最小值; if (initialDpr) { dpr = parseFloat(initialDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } if (maximumDpr) { dpr = parseFloat(maximumDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } }
第三、如果 dpr &scale都沒有設定,那麼就通過裝置的dpr設定起縮放 scale
if (!dpr && !scale) {//meta[name="viewport"]&&meta[name="flexible"]都不存在。 var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,對於2和3的屏,用2倍的方案,其餘的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其他裝置下,仍舊使用1倍的方案 dpr = 1; } scale = 1 / dpr; }
第四、得到scale之後 ,如果meta 的viewport不存在,那麼就建立一meta[name=“viewport”],將scale配置進去
metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');// width=device-width,可省略 if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); }
第五、動態改寫html的font-size
var width = docEl.getBoundingClientRect().width;//獲取html的寬度 if (width / dpr > 540) {//判斷螢幕邏輯畫素大於540時,取540 width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem;
有關網易與手淘的適配參考:
ofollow,noindex"> https://segmentfault.com/a/1190000007526917
http://caibaojian.com/mobile-responsive-example.html
vw單位方案:
//750px設計稿 html{ font-size: 13.3333vw;//(100px/750px)*100vw }
vw方案參考:
https://blog.csdn.net/sky2714/article/details/80849863
https://blog.csdn.net/u013778905/article/details/78729468
最後,有關使用rem遇到的問題請參考: