灏天阁

css 移动端适配最佳实践

· Yin灏

移动端适配,在移动端里经常有遇到,在不同分辨率移动端设备精确还原 UI 设计稿,这是一个令人抓狂的问题,好在有flexbox布局解决了自适应很大一部分问题。

在开始本文之前主要介绍几种笔者常用的适配方案

1、设置meta标签的initial-scale,mininum-scale,maxinum-scale缩放比

2、rem适配,利用根设置基础单位

3、vw+calc,结合rem适配

正文开始…

meta 缩放比

(function () {
  let timer = null;
  function flexable() {
    const deviceWidth = window.screen.width;
    // 根据当前设计稿,如果是设计稿640,那么targetWidth就是320,设计稿实际1px,页面也是1px
    // 如果设计稿是750,那么targetWidth就是375
    const targetWidth = 320;
    const scale = deviceWidth / targetWidth;
    let meta = document.querySelector('meta[name="viewport"]');
    if (!meta) {
      const meta = document.createElement("meta");
      meta.setAttribute("name", "viewport");
      meta.setAttribute(
        "content",
        `width=device-width,initial-scale=${scale},minimum-scale=${scale},maximum-scale=${scale},user-scalable=no`
      );
      document.getElementsByTagName("head")[0].appendChild(meta);
    }
    if (meta) {
      meta.setAttribute(
        "content",
        `width=device-width,initial-scale=${scale},minimum-scale=${scale},maximum-scale=${scale},user-scalable=no`
      );
    }
  }
  window.addEventListener(
    "resize",
    () => {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        flexable();
      }, 80);
    },
    false
  );
  flexable();
})();

主要是设置根据window.screen.width与设计稿实际尺寸targetWidth计算出scale,将这个scale动态设置metacontent,width=device-width,initial-scale=scale,minimum-scale=scale,maximun-scale=scale

当我们动态设置meta后,我们不同分辨率下的字体大小就会动态的发生变化

640x960

750x1334

注意targetWidth是你设计稿尺寸,如果是750的设计稿,那么就是375,在设计稿中量的是多少尺寸,就是多少固定尺寸

rem 适配

因为默认浏览器字体的大小就是16px,所以我们在一些项目中会看到font-size:62.5%

62.5%到底怎么计算来的呢,如果我们根 html 设置font-size: 16px

1rem = 16px;

换算成百分比就是1/16就是6.25%,现在我们扩大 10 倍就是62.5%,所以1rem = 10px,也就1px=0.1rem

在我们根据 UI 设计稿实际尺寸中,如果量得尺寸是16px那么就是1.6rem,只需要在原单位基础上/10即可

注意我们meta标签上同样要默认设置<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>rem</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      html {
        font-size: 62.5%;
      }
      .title {
        font-size: 2rem;
      }
      .box {
        max-width: 64rem;
        height: 10rem;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="title">rem适配</div>
      <div class="box"></div>
    </div>
  </body>
</html>

这种方案在早期移动端 rem 适配用得比较多

vw 适配

vw是视口单位,通常来讲会将可视区域分成100vw

在利用vwcalc来设置根htmlfont-size,然后用rem单位

然后我们看下代

* {
  padding: 0;
  margin: 0;
}
html {
  font-size: calc(100vw / 320 * 10);
}

100vw瓜分了320分辨率,然后我们需要扩大 10 倍

1rem = 10vw = 10px

所以当我们实际量得 UI 上20px时,我们直接计算得出2rem即可

#app {
  position: relative;
}
.title {
  font-size: 2rem;
}
.box {
  max-width: 32rem;
  height: 10rem;
  background-color: red;
}
.content {
  font-size: 2rem;
  position: absolute;
  top: 0px;
  z-index: 1;
  background-color: rgb(255, 0, 0, 0.1);
}
.row-present .col {
  /* width: calc(100% / 3); */
  width: 20%;
  height: 100px;
  float: left;
  color: green;
  font-size: 20px;
}
:root {
  --background-color: #111;
}
.row-present .col:nth-of-type(2n + 1) {
  background-color: var(--background-color);
}
p.title {
  clear: both;
}
.row-vw .col {
  float: left;
  height: 100px;
  width: 20vw;
  color: green;
  font-size: 2rem;
}
.row-vw .col:nth-of-type(2n + 1) {
  background-color: var(--background-color);
}

最后的结果就是下面

总结

  • 可以动态设置metainitial-scale的缩放比,主要是根据screen.width设备宽度与目标设计稿targetWidth形成像素比 scale,假设设计稿是750的,那么我们的targetWidth就是 375,设计稿量的尺寸就是 10px,网页上所写的元素也是 10px,因为scale=1,随着不同分辨率scale的值也会发生变化
  • rem 适配,浏览器默认font-size:16px,当我们根font-size:62.5%时,我们利用rem单位设置元素单位,1rem=10px,所以当设计稿 750 像素时,量尺寸20px,那么你实际单位换成 rem 时,就是2rem,原有尺寸缩小 10 倍即可,这种方案会有一定误差,但也基本满足移动端自适应
  • vw+calc+rem方案,同样是设置根html的单位,主要是font-size: calc(100vw / targetWidth * 10),我们把vw视口单位,如果你的设计稿是 640,100vw就是targetWidth=320像素,如果你的设计稿是 750,那么targetWidth=3751rem = 10vw = 10px,所以当你 750 的设计稿 20 像素时,那么在实际网页的单位只需要缩小 10 倍即可,也就是 2rem,这种方式精确度高,简单,基本不需要第三方什么适配 js
  • 本文 code example

- Book Lists -