移动端自适应布局方案尝试

qzbs0963 8年前
   <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>