首页 > 技术文章 > 响应式布局要素

lisaShare 2019-05-18 14:29 原文

  1. 宽高百分比,不要固定死;
  2. 弹性盒flex css3;
  3. 单位(em、rem)px;
  4. 媒体查询 - 利器 @media switch 960-1200;(媒体查询加不加 screen 的区别是加上后打印不出screen的样式,有些可以单独写@media print { ... })
  5. gtid布局 - 网格布局;
  6. view port - 手机布局利器;
  7. 框架布局 - bootstrap、amazeUI、pure 等等几百种;

rem 原理

字体单位:值根据html根元素大小而定,同样可以作为宽度,高度等单位。
适配原理:将px替换成rem,动态修改html的fonts-size适配。
兼容醒:ios6以上和android 2.1以上,基本覆盖所有流行的手机系统。

em

根据父元素字体大小的倍数设置。

css3自适应布局单位vw、vh

视口单位(Viewport units)
什么是视口?
在PC端,视口指的是在PC端,指的是浏览器的可视区域;
而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Viewport(视觉视口),Ideal Viewport(理想视口)。
视口单位中的“视口”,PC端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport。
根据CSS3规范,视口单位主要包括以下4个:
1.vw:1vw等于视口宽度的1%。
2.vh:1vh等于视口高度的1%。
3.vmin:选取vw和vh中最小的那个。
4.vmax:选取vw和vh中最大的那个。
vh and vw:相对于视口的高度和宽度,而不是父元素的(CSS百分比是相对于包含它的最近的父元素的高度和宽度)。1vh 等于1/100的视口高度,1vw 等于1/100的视口宽度。
比如:浏览器高度950px,宽度为1920px, 1 vh = 950px/100 = 9.5 px,1vw = 1920px/100 =19.2 px。
vmax相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax。
vmin相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin。

height: calc(750rpx / 2.3),这里2.3是image的宽高比

下面是工作中用到的移动端rem布局

// 一倍图
//兼容UC竖屏转横屏出现的BUG
//自定义设计稿的宽度:designWidth
//最大宽度:maxWidth
//这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750)
;(function(designWidth, maxWidth) {
  var doc = document,
      win = window,
      docEl = doc.documentElement,
      remStyle = document.createElement("style"),
      tid;

  function refreshRem() {
      var width = docEl.getBoundingClientRect().width;
      maxWidth = maxWidth || 540;
      width>maxWidth && (width=maxWidth);
      var rem = width * 100 / designWidth;
      remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
  }

  if (docEl.firstElementChild) {
      docEl.firstElementChild.appendChild(remStyle);
  } else {
      var wrap = doc.createElement("div");
      wrap.appendChild(remStyle);
      doc.write(wrap.innerHTML);
      wrap = null;
  }
  //要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
  refreshRem();

  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 = "16px";
  } else {
      doc.addEventListener("DOMContentLoaded", function(e) {
      doc.body.style.fontSize = "16px";
      }, false);
  }
  })(750, 750);
// 二倍图 @rem: 100rem;
;(function(designWidth, maxWidth) {
  var doc = document,
      win = window,
      docEl = doc.documentElement,
      remStyle = document.createElement("style"),
      tid;

  function refreshRem() {
      var width = docEl.getBoundingClientRect().width;
      maxWidth = maxWidth || 540;
      // if(width > 998) width = 375 // 添加这段且配置上媒体查询可以在pc上显示小图
      width>maxWidth && (width=maxWidth);
      var rem = width * 100 / designWidth;
      remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
  }

  if (docEl.firstElementChild) {
      docEl.firstElementChild.appendChild(remStyle);
  } else {
      var wrap = doc.createElement("div");
      wrap.appendChild(remStyle);
      doc.write(wrap.innerHTML);
      wrap = null;
  }
  //要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
  refreshRem();

  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 = "16px";
  } else {
      doc.addEventListener("DOMContentLoaded", function(e) {
      doc.body.style.fontSize = "16px";
      }, false);
  }
  })(375, 750);

rem_pc

!function(doc, win) {
  var cw = 1920
  function fontSizeInit() {
    var html = doc.documentElement;
    var hwidth = html.getBoundingClientRect().width;
    hwidth < 768 && (hwidth = 768);
    html.style.fontSize = 100*(hwidth/cw) + 'px'
  }
  fontSizeInit();
  var reTimeoutId;
  win.onresize = function () {
    reTimeoutId && clearTimeout(reTimeoutId);
    reTimeoutId = setTimeout(function(){
      fontSizeInit();
    }, 100)
  };
}(document, window);

淘宝flexible.js + rem @37.5rem;

!function(e,t){function n(){t.body?t.body.style.fontSize=12*o+"px":t.addEventListener("DOMContentLoaded",n)}function d(){var e=i.clientWidth/10;i.style.fontSize=Math.min(39,e)+"px"}var i=t.documentElement,o=e.devicePixelRatio||1;if(n(),d(),e.addEventListener("resize",d),e.addEventListener("pageshow",function(e){e.persisted&&d()}),o>=2){var a=t.createElement("body"),s=t.createElement("div");s.style.border=".5px solid transparent",a.appendChild(s),i.appendChild(a),1===s.offsetHeight&&i.classList.add("hairlines"),i.removeChild(a)}}(window,document);

or

!function(e,t){function n(){t.body?t.body.style.fontSize=12*o+"px":t.addEventListener("DOMContentLoaded",n)}function d(){var e=i.clientWidth/10;i.style.fontSize=Math.min(64,e)+"px"}var i=t.documentElement,o=e.devicePixelRatio||1;if(n(),d(),e.addEventListener("resize",d),e.addEventListener("pageshow",function(e){e.persisted&&d()}),o>=2){var a=t.createElement("body"),s=t.createElement("div");s.style.border=".5px solid transparent",a.appendChild(s),i.appendChild(a),1===s.offsetHeight&&i.classList.add("hairlines"),i.removeChild(a)}}(window,document);
@media screen and (min-width: 992px) and (max-height:579px)  {
    .wrapper {
        height: 558px;
        top: 50%;
        transform: translateY(-50%);
        // left: 50%;
        // transform: translate(-50%, -50%);
    }
}

@media screen and (min-width: 992px) {
    .wrapper {
      width: 375px;
      height: 667px;
      top: 48%;
      transform: translateY(-50%);
    //   left: 50%;
    //   transform: translate(-50%, -50%);
    ::-webkit-scrollbar {
        display: block;
    }
    /*  谷歌内核设置滚动条 */
    ::-webkit-scrollbar-thumb {
        height: 50px;
        outline-offset: -2px;
        outline: #fff solid 2px;
        border: 2px solid #fff;
        background-color: #b2b3b4;
        border-radius: 4px
    }
    
    ::-webkit-scrollbar-thumb:hover {
        height: 50px;
        background-color: rgb(172, 208, 236);
        border-radius: 4px
    }
    
    ::-webkit-scrollbar {
        width: 8px;
        height: 8px
    }
    
    ::-webkit-scrollbar-track-piece {
        background-color: transparent;
        border-radius: 0
    } 
    }
    body {
        ::-webkit-scrollbar {
            display: none;
        }
    }
}

@media screen and (max-width: 992px) {
    ::-webkit-scrollbar {
      display: none;
    }
}

推荐阅读