以前寫移動端都是用這段JS解決.
(function (doc, win) { // 分辨率Resolution適配 var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; if (!clientWidth) return; if (clientWidth >= 750) { docEl.style.fontSize = 100 + 'px'; }else{docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';} } // Abort if browser does not support addEventListener if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); recalc(); })(document, window);
JS中設計稿的大小可以隨便改,我這里用的設計稿都是750的,將750尺寸下,根元素font-size大小設置成100px,用這個JS可以實現頁面隨根元素的font-size大小而改變,也就是rem寫法.當設計稿中元素大小為100px時候,只要在css中設置成1rem就可以.計算很方便,這樣寫確實簡單.
但這個JS有一些很難受的弊端,其一在現在iphone和其它手機中,dpr值都為2或者3,這樣會出現移動端1px這個不是1px的難題,會是2px 3px的大小.這樣會導致給一個文字加邊框文字會塌下去的問題.
字體大小在dpr=2的iphone設備只能設置到24px,原理如下375*24/750=12,瀏覽器最小設置字體大小為12.ipone5的真實大小是375pt.也就是真實設計稿750px的一半大.
dpr=3的設備也只能設置到12*750/414=21.74px.所以弊端不少.ipone6plus的真實大小是414pt.
不懂 dpr pt px的可以去網上問問,理解就可以.
前段時間看到網上有個hotcss解決方案,我研究了一下代碼.代碼如下(做了簡單的修改,原因下文中有):
(function( window , document ){ 'use strict'; //給hotcss開辟個命名空間,別問我為什么,我要給你准備你會用到的方法,免得用到的時候還要自己寫。 var hotcss = {}; (function() { //根據devicePixelRatio自定計算scale //可以有效解決移動端1px這個世紀難題。 var viewportEl = document.querySelector('meta[name="viewport"]'), hotcssEl = document.querySelector('meta[name="hotcss"]'), dpr = window.devicePixelRatio || 1, maxWidth = 750,//最大顯示尺寸 designWidth = 0; dpr = dpr >= 3 ? 3 : ( dpr >=2 ? 2 : 1 ); //允許通過自定義name為hotcss的meta頭,通過initial-dpr來強制定義頁面縮放 if (hotcssEl) { var hotcssCon = hotcssEl.getAttribute('content'); if (hotcssCon) { var initialDprMatch = hotcssCon.match(/initial\-dpr=([\d\.]+)/); if (initialDprMatch) { dpr = parseFloat(initialDprMatch[1]); } var maxWidthMatch = hotcssCon.match(/max\-width=([\d\.]+)/); if (maxWidthMatch) { maxWidth = parseFloat(maxWidthMatch[1]); } var designWidthMatch = hotcssCon.match(/design\-width=([\d\.]+)/); if (designWidthMatch) { designWidth = parseFloat(designWidthMatch[1]); } } } document.documentElement.setAttribute('data-dpr', dpr); hotcss.dpr = dpr; document.documentElement.setAttribute('max-width', maxWidth); hotcss.maxWidth = maxWidth; if( designWidth ){ document.documentElement.setAttribute('design-width', designWidth); hotcss.designWidth = designWidth; } var scale = 1 / dpr, content = 'width=device-width, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + ', user-scalable=no'; if (viewportEl) { viewportEl.setAttribute('content', content); } else { viewportEl = document.createElement('meta'); viewportEl.setAttribute('name', 'viewport'); viewportEl.setAttribute('content', content); document.head.appendChild(viewportEl); } })(); hotcss.px2rem = function( px , designWidth ){ //預判你將會在JS中用到尺寸,特提供一個方法助你在JS中將px轉為rem。就是這么貼心。 if( !designWidth ){ //如果你在JS中大量用到此方法,建議直接定義 hotcss.designWidth 來定義設計圖尺寸; //否則可以在第二個參數告訴我你的設計圖是多大。 designWidth = parseInt(hotcss.designWidth , 10); } return parseInt(px,10)*750/designWidth/100; } hotcss.rem2px = function( rem , designWidth ){ //新增一個rem2px的方法。用法和px2rem一致。 if( !designWidth ){ designWidth = parseInt(hotcss.designWidth , 10); } //rem可能為小數,這里不再做處理了 return rem*100*designWidth/750; } hotcss.mresize = function(){ //對,這個就是核心方法了,給HTML設置font-size。 var innerWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth; if( hotcss.maxWidth && (innerWidth/hotcss.dpr > hotcss.maxWidth) ){ innerWidth = hotcss.maxWidth*hotcss.dpr; } if( !innerWidth ){ return false;} document.documentElement.style.fontSize = ( innerWidth*100/750 ) + 'px';//設計尺寸750 根元素為100px 便於計算 hotcss.callback && hotcss.callback(); }; hotcss.mresize(); //直接調用一次 window.addEventListener( 'resize' , function(){ clearTimeout( hotcss.tid ); hotcss.tid = setTimeout( hotcss.mresize , 33 ); } , false ); //綁定resize的時候調用 window.addEventListener( 'load' , hotcss.mresize , false ); //防止不明原因的bug。load之后再調用一次。 setTimeout(function(){ hotcss.mresize(); //防止某些機型怪異現象,異步再調用一次 },333) window.hotcss = hotcss; //命名空間暴露給你,控制權交給你,想怎么調怎么調。 })( window , document );
這樣寫出來的方案就考慮到了dpr值的影響,以上問題都可以解決掉,他們的CSS是用sass實時去編譯計算的,
寬高這么寫width:px2rem(182);height:px2rem(53);
下邊這個函數就是用來解決這個算法的.
@function px2rem( $px ){
@return $px*320/$designWidth/20 + rem;
}
他的JS我稍微做了修改,因為老去寫px2rem()這個方法煩的很,所以我把里邊計算根元素字體大小這句改成如下
document.documentElement.style.fontSize = ( innerWidth*100/750 ) + 'px';//設計尺寸750 根元素為100px 便於計算
這樣做的原因如下,我的設計稿一直都是750px,在這個尺寸下我將根元素字體大小設置成100px,這樣我設計稿上的元素高是98px的時候,我直接設置成0.98rem;這樣簡單的計算一下,速度很快,也不會去寫px2rem()這個方法;
如果寫個簡單活動頁面,也可以不用sass 老去監聽編譯,測試也麻煩.直接口算簡單易用.
如果你的設計稿是720,這句話應該為
document.documentElement.style.fontSize = ( innerWidth*100/720 ) + 'px';