移动端自适应布局方案尝试
<h2><strong>问题</strong></h2> <p>刚开始接触移动端H5页面的时候最困扰的几个问题是:</p> <ol> <li>6或6p上明明是1px的边框怎么就成了2px或3px辣么粗!</li> <li>图片,div等如何等比自适应设计图</li> </ol> <p>后来慢慢知道了第一点是由于retina屏幕下设备像素比的问题造成,第二点知道了单位rem。</p> <h2><strong>目的</strong></h2> <p>不想因为使用rem而一一去计算设计稿的尺寸,设计稿750的尺寸的标注可以直接在sass中使用;字体不使用rem缩放,原因是:</p> <p>显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。</p> <p>还一个目的是,在页面没有设置viewport的时候动态设置,并且不让页面有一个“闪现”的过程(也就是刚加载没设置的状态到设置的状态);页面动态变化时,尺寸相应变化;</p> <h2><strong>尝试</strong></h2> <p>在写H5页面的时候,尽可能少的去写meta标签,我会这样做:</p> <pre> <head> <title>viewport test</title> <meta charset="utf-8"> <link rel="stylesheet" href="style/style.css"> </head></pre> <p>就这样简单,然后实现的代码当然是放在head里。因为并没有写viewport,所以得判断加上</p> <pre> if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } }</pre> <p>然后根据页面的devicePixelRatio缩放</p> <pre> var scale = parseFloat((1 / dpr).toFixed(2)); if (dpr != 1) { metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no'); }</pre> <p>设置根字体大小</p> <pre> // document width function setDocumentFontSize () { var width = docEl.getBoundingClientRect().width; docEl.style.fontSize = width / 10 + 'px'; } setDocumentFontSize();</pre> <p>页面resize监听</p> <pre> var timer; win.addEventListener('resize', function() { clearTimeout(timer); timer = setTimeout(function () { setDocumentFontSize(); }, 300); }, false);</pre> <p>为了字体不使用rem,需要为documentElement设置data-dpr属性</p> <pre> // document data-dpr set font-size px var dpr = window.devicePixelRatio; if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } docEl.setAttribute('data-dpr', dpr);</pre> <p>sass相关设置</p> <p>完全根据设计稿尺寸写</p> <pre> // baseFontSize $baseFontSize: 75; @function px2rem($px){ @return $px/$baseFontSize * 1rem; } @function px2rem2($px){ @return px2rem($px*2); }</pre> <p>字体大小变化</p> <pre> // 字体大小计算 @mixin font-dpr($font-size){ font-size: $font-size; [data-dpr="2"] & { font-size: $font-size * 2; } [data-dpr="3"] & { font-size: $font-size * 3; } }</pre> <p>例如:一个简单样式的设置</p> <pre> .test { @include font-dpr(10px); width: px2rem2(300); margin: 0 auto; border:1px #dcdcdc solid; } img { display: block; width: px2rem2(355); margin: 0 auto; }</pre> <p>效果示例:</p> <p><img src="https://simg.open-open.com/show/6fa96f802f0f02e059cae788c7fec21b.png"></p> <p>可以从图中看出,6p的dpr为3,字体相应为30px,页面缩放了3倍,正式我所想要的(图片可以右键在新的窗口打开看大图)。</p> <p>页面demo源码</p> <pre> <!DOCTYPE html> <html> <head> <title>viewport test</title> <meta charset="utf-8"> <link rel="stylesheet" href="style/style.css"> <script> ;(function (win) { var doc = win.document; var docEl = doc.documentElement; var metaEl = doc.querySelector('meta[name="viewport"]'); if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } // document data-dpr set font-size px var dpr = window.devicePixelRatio; if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } docEl.setAttribute('data-dpr', dpr); var scale = parseFloat((1 / dpr).toFixed(2)); if (dpr != 1) { metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no'); } // document width function setDocumentFontSize () { var width = docEl.getBoundingClientRect().width; docEl.style.fontSize = width / 10 + 'px'; } setDocumentFontSize(); var timer; win.addEventListener('resize', function() { clearTimeout(timer); timer = setTimeout(function () { setDocumentFontSize(); }, 300); }, false); })(window); </script> </head> <body> <div class="test"> 显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。 </div> <img src="https://camo.githubusercontent.com/3bd9e24ee11cee86e81dc49c0e5722e9f55e7297/687474703a2f2f7777772e773363706c75732e636f6d2f73697465732f64656661756c742f66696c65732f626c6f67732f323031352f313531312f72656d2d392e6a7067" alt=""> </body> </html></pre> <p> </p> <p> </p> <p>来自:http://ymblog.net/2016/09/23/viewport/</p> <p> </p>
本文由用户 qzbs0963 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!