简述移动端常见的布局方式

1、响应式布局:px

  • 概念:

           响应式网页设计就是一个网站能够兼容多个终端-----而不是为每个终端做一个特定的版本;

           其目的是为用户提供更加舒适的界面和更好的用户体验;

  • 优缺点:
    • 优点:
      • 面对不同分辨率设备灵活性强;
      • 能够快捷解决多设备显示适应问题;
    • 缺点:
      • 兼容各种设备工作量大,效率低下;
      • 代码累赘,会出现隐藏无用代码,加载时间过长;
  • 步骤:
    • 设置meta标签(App.vue或者首html文件)
      <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1,user-scalable=no">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
      <meta name="HandheldFriendly" content="true">
      //user-scalable属性能够解决ipad切换横屏之后触摸才能回到具体尺寸的问题。
    • 通过媒体查询来设置样式media query(media query 是响应式设计的核心,它能够和浏览器进行沟通,告诉浏览器页面如何呈现)
      @media screen and (max-width:980px){//设置不同设备中div的布局方式
           #head { … }
           #content { … }
           #footer { … }
      }这里面的样式会覆盖掉之前所定义的样式。
    • 设置多种视图宽度
      /**ipad**/
      @media only screen and (min-width:768px)and(max-width:1024px){    }
      /**iphone**/
       @media only screen and (width:320px)and (width:768px){     }
    • 字体设置(一般rem更方便使用)https://www.cnblogs.com/YYvam1288/p/5123272.html
      @media screen and (min-width: 768px) {
        html,
        body {
          font-size: 8px !important;
        }
      }
      
      @media screen and (min-width: 992px) {
        html,
        body {
          font-size: 10px !important;
        }
      }
      
      @media screen and (min-width: 1200px) {
        html,
        body {
          font-size: 14px !important;
        }
      }
      
      @media screen and (min-width: 1500px) {
        html,
        body {
          font-size: 16px !important;
        }
      }
      
      html,
      body {
        font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
          "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
        height: 100%;
        width: 100%;
        margin: 0px;
        padding: 0px;
      }
      
      * {//怪异盒模型也就是IE盒模型
        box-sizing: border-box;
      }
  • 响应式布局所涉及到的问题:
    • 图片液态化:
      img{//要保证所有图片最大显示为其自身的100%(即最大只可以显示为自身那么大),不可以使用width:100%,会让图片跟他的容器一样宽
          max-width:100%;
          height:auto;  
      }

2、弹性布局(百分比布局、流式布局)

百分比能够设置的属性是width、height、padding、margin。其他属性比如border、font-size不能用百分比设置的。
如果用百分比写width,那么指的是父元素width的百分之多少。 如果用百分比写height,那么指的是父元素height的百分之多少。 如果用百分比写padding,那么指的是父元素width的百分之(无视padding)多少,无论是水平的padding还是竖直的padding。 如果用百分比写margin,那么指的是父元素width的百分之(无视padding)多少,无论是水平的margin还是竖直的margin。
不能用百分比写border的宽度

3、rem布局(css3新增属性)插件:cssrem(IE8一下不兼容)

  • 概念:rem是相对于根元素(html)的字体大小的单位;

                 em一般都是以<body>的“font-size”为基准(表示父元素的字号的倍数);

body{
  font-size:10px;  
}
p{
  font-size:1.4em;//14px
}
例子:
bootstrap样式表,html {font-size:62.5%;}  body {font-size:14px;},
p{font-size:1em;)//14px
  • 优点:既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应;
  • rem的计算方式:
    1、确定基数:一般10px,自己记住就行,不用写进代码里
    2、html {font-size:百分数;}    百分数=基数/16  
      基数10    百分数62.5%
      基数14    百分数87.5%
    3、px换算rem   公式=想要的px值/基数
      也就是说,当你设置 html {font-size:62.5%;},你想给容器里的文字设置字号14px,换算成rem就是14px/10——1.4rem 这样子
      (如果自己想要测试的话,拿火狐Firebug测试,因为Chrome下字号低于12px失效哈,如果想设置小于12px的字号,Chrome也有解决方案,自己百度就好)
  • 应用于:
  • 只使用rem会出现在retina屏幕上1px线条显示过粗的现象,因为虽然物理尺寸一致,但在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。

 4、flexible布局(自动通过flexible.js计算页面htmlfont-size的大小,然后在页面布局中使用rem作为单位,而非px)

  注意:(手机淘宝推出的,为了解决淘宝H5在移动端的布局)https://www.cnblogs.com/lyzg/p/5058356.html

  • 在使用flexible.js的过程中,如果当前页面(app.vue/index.html)指定了meta[name="viewport"],删除meta标签,然后根据js文件重新计算dpr;
  • dpr = 物理像素/设备像素(750/375)
  • 当设计稿为  750px 的情况下,dpr(设备像素比)=2,根元素字体大小为100px,除font-size外,公式=想要的px值/100 ;
  • font-size推荐使用px写死
    • 工作中做完一个触屏版的页面后,我们会拿iPhone5s、iPhone6、iPhone6s等手机进行测试,他们都是Retina屏,我们当然希望在这些手机型号上看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本(例如iPhone7、iPhone7Plus)。另外,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,都是偶数,所以我们不希望出现13px和15px这样的奇葩尺寸。
      如此一来,就决定了在制作H5的页面中,rem并不适合用到段落文本上。所以在Flexible整个适配方案中,考虑文本还是使用px作为单位。只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小。

      //当然这只是针对于描述性的文本,比如说段落文本。但有的时候文本的字号也需要分场景的,比如在项目中有一个slogan,
      //业务方希望这个slogan能根据不同的终端适配。针对这样的场景,完全可以使用rem给slogan做计量单位
      //移动端的字体选择。对于只需要适配手机设备,使用px即可。对于需要适配各种移动设备,
      //例如需要适配iPhone和iPad等分辨率差别比较挺大的设备,就要使用rem了,有时还需要配合媒体查询一起使用。
      //方法 定制一个font-dpr()这样的Sass混合宏 @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; } }
      //开发中
      @include font-dpr(16px);
       
  • iPhone6 上有1px 的滚动条,最后处理方案是通过 viewport 中的 maximum-scale 的值加了0.1,由于设置了user-scalable=no,maximum-scale 的值加0.1并不会有什么影响,但是却神奇的解决了这个问题。
  • 下面为js代码,只需要将其复制到js文件,并将其命名为flexible.js
    (function(win, lib) {
         var doc = win.document;
         var docEl = doc.documentElement;
         var metaEl = doc.querySelector('meta[name="viewport"]');
         var flexibleEl = doc.querySelector('meta[name="flexible"]');
         var dpr = 0;
         var scale = 0;
         var tid;
         var flexible = lib.flexible || (lib.flexible = {});
    
         if (metaEl) {
     //        console.warn('将根据已有的meta标签来设置缩放比例');
             var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
             if (match) {
                 scale = parseFloat(match[1]);
                 dpr = parseInt(1 / scale);
             }
         } else if (flexibleEl) {
             var content = flexibleEl.getAttribute('content');
             if (content) {
                 var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
                 var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
                 if (initialDpr) {
                     dpr = parseFloat(initialDpr[1]);
                     scale = parseFloat((1 / dpr).toFixed(2));
                 }
                 if (maximumDpr) {
                     dpr = parseFloat(maximumDpr[1]);
                     scale = parseFloat((1 / dpr).toFixed(2));
                 }
             }
         }
    
         if (!dpr && !scale) {
             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;
         }
    
         docEl.setAttribute('data-dpr', dpr);
         if (!metaEl) {
             metaEl = doc.createElement('meta');
             metaEl.setAttribute('name', 'viewport');
             metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
             if (docEl.firstElementChild) {
                 docEl.firstElementChild.appendChild(metaEl);
             } else {
                 var wrap = doc.createElement('div');
                 wrap.appendChild(metaEl);
                 doc.write(wrap.innerHTML);
             }
         }
    
         function refreshRem(){
             var width = docEl.getBoundingClientRect().width;
           //  console.log(width)
             if (width / dpr > 768) {
                 width = 768 * dpr;
             }
             var rem = width / 7.5;
             docEl.style.fontSize = rem + 'px';
             flexible.rem = win.rem = rem;
         }
    
         win.addEventListener('resize', function() {
             clearTimeout(tid);
             tid = setTimeout(refreshRem, 300);
         }, false);
         win.addEventListener('pageshow', function(e) {
             if (e.persisted) {
                 clearTimeout(tid);
                 tid = setTimeout(refreshRem, 300);
             }
         }, false);
    
         if (doc.readyState === 'complete') {
             doc.body.style.fontSize = 12 * dpr + 'px';
         } else {
             doc.addEventListener('DOMContentLoaded', function(e) {
                 doc.body.style.fontSize = 12 * dpr + 'px';
             }, false);
         }
    
    
         refreshRem();
    
         flexible.dpr = win.dpr = dpr;
         flexible.refreshRem = refreshRem;
         flexible.rem2px = function(d) {
             var val = parseFloat(d) * this.rem;
             if (typeof d === 'string' && d.match(/rem$/)) {
                 val += 'px';
             }
             return val;
         }
         flexible.px2rem = function(d) {
             var val = parseFloat(d) / this.rem;
             if (typeof d === 'string' && d.match(/px$/)) {
                 val += 'rem';
             }
             return val;
         }
    
     })(window, window['lib'] || (window['lib'] = {}));
    View Code
  •  混合开发需要做到的兼容处理
    1.如果dpr=1(如电脑端),则html的font-size为50px,此时 1rem = 50px, viewport 的 initial-scale 、minimum-scale 和 maximum-scale 都为 “1.0” ; 
    2.如果dpr=2(如iphone 5 和 6),则html的font-size为100px,此时 1rem = 100px, viewport 的 initial-scale 、minimum-scale 和 maximum-scale 都为 “0.5” 
    3.如果dpr=3(如iphone 6 sp),则html的font-size为150px,此时 1rem = 150px; viewport 的 initial-scale 、minimum-scale 和 maximum-scale 都为 “0.3333333333”

4、常见的适配布局组合:

5、参考资料:

https://www.cnblogs.com/fengyingwang/p/6073795.html

https://www.cnblogs.com/YYvam1288/p/5123272.html

posted @ 2019-07-08 17:34  北栀女孩儿  阅读(1331)  评论(0编辑  收藏  举报