乐趣区

移动端REM适配的基本实现

  REM 是移动端屏幕适配的常见方案,可以选用淘宝开源的 flexible,只是用起来稍微有一点麻烦,我一般采用更加简洁的方案,动态去计算 html 跟标签的 font-size,监听屏幕的尺寸变化及时响应,兼顾用户修改系统字体时的处理等其它细节。
  采用 VW 方案去适配也是一个好办法,只是兼容性不太好,需要根据具体场景去选择。

开始使用

  1. 压缩后,放置到 head 标签的尾部,直接 script 标签嵌入,保证最先执行,避免用户感知到页面跳动;
  2. 建议加如下代码,将默认字体大小重置为 16px,避免在 js 未执行时,样式、字体混乱:

    html,
    body {font-size: 16px;}
  3. 字体需不需要使用 rem 单位?看产品、设计师的定位吧,通常建议不要对字体使用 rem 单位(牵扯到布局还是应该采用 rem 单位),尤其是大段的文章;

代码

<script>
/*
 * REM 适配:*   1. 动态设置 html 标签 font-size;*   2. 动态设置 html 标签 data-dpr、data-img-rate 属性;*   3. 用户调整系统字体大小时,避免页面样式错乱;*   4. 计算公式:*      750 的设计稿,量图的大小 / 100 => rem 数值
 */

(function (document, window) {
  var docEl = document.documentElement,
    user_webset_font, // 用户设置的浏览器的字体大小 (兼容 ie)
    rate = 1, // 用户设置的字体大小和默认 16px 的比例系数
    resizeEvent = 'orientationchange' in window ? 'orientationchange' : 'resize';

  if (docEl.currentStyle) {user_webset_font = docEl.currentStyle['fontSize'];
  } else {user_webset_font = getComputedStyle(docEl, false)['fontSize'];
  }

  // 用户调整系统字体大小或浏览器字体大小时,需要做兼容。rate = parseFloat(user_webset_font) / 16;

  /**
   * 设置 html 标签 font-size
   */
  var resetRootFontSize = function () {
    var clientWidth = docEl.clientWidth;

    if (!clientWidth) return;

    if (clientWidth >= 1080) {docEl.style.fontSize = 200 / rate + 'px';} else {
      // 750 设计稿
      docEl.style.fontSize = 100 * (clientWidth / 750) / rate + 'px';
      // 375 设计稿
      // docEl.style.fontSize = 100 * (clientWidth / 375) / rate + 'px';
    }
  }

  /**
   * 设置 html 的 data-dpr/data-img 属性(供选用而设置)。*/
  var resetDpr = function () {if (!window.devicePixelRatio) return;
    // 屏幕像素比大于等于 3, 采用 3 倍图, 否则使用 2 倍图.
    var imgRate = window.devicePixelRatio >= 3 ? 3 : 2;

    docEl.setAttribute('data-dpr', window.devicePixelRatio);
    docEl.setAttribute('data-img-rate', imgRate);
  }

  // 直接执行,不放到 DOMContentLoaded 事件执行,否则页面能感知到跳动
  resetRootFontSize();
  resetDpr();

  if (!window.addEventListener) return;
  window.addEventListener(resizeEvent, function () {resetRootFontSize();
    resetDpr();}, false)
})(document, window);
</script>
退出移动版