移动端适配的几种方案记录

思路

  1. 写页面时,按照设计稿写固定宽度,最后再统一缩放处理,在不同手机上都能用
  2. 按照设计稿的标准开发页面,在手机上部分内容根据屏幕宽度等比缩放,部分内容按需要变化,需要缩放的元素使用rem|| vw相对单位,不需要缩放的使用px
  3. 固定尺寸+弹性布局,不需要缩放(viewportvmrem)但是等比适配,放在ipad上的时候(设计稿以手机屏幕设计),页面的元素会很大很丑,所以并不是所有的场景下,页面都做整体的缩放(viewport 自动处理的也很好了)。利用合理的布局也可以比如flexgrid

viewport 适配

2

设计稿的宽度为750px,写完页面之后元素自动缩小,适配375px宽度的屏幕。

<meta name="viewport" content="width=750,initial-scale=0.5">

inital-scale = 屏幕的宽度 / 设计稿的宽度。但是移动端的屏幕肯定不止一种宽度,所以需要动态的设置 inital-scale的值。

<head>
  <script>
    const WIDTH = 750
    const mobileAdapter = () => {
      let scale = screen.width / WIDTH
      let content = `width=${WIDTH}, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}`
      let meta = document.querySelector('meta[name=viewport]')
      if (!meta) {
        meta = document.createElement('meta')
        meta.setAttribute('name', 'viewport')
        document.head.appendChild(meta)
      }
      meta.setAttribute('content',content)
    }
    mobileAdapter()
    window.onorientationchange = mobileAdapter //屏幕翻转时再次执行,翻转屏幕的时候高度和宽度对换
  </script>
</head>

document.querySelector('meta[name=viewport]')

image-20211014140709642

缺点:

边线的问题,不同尺寸下,等比缩放之后边线的粗细不一样。而且全部的元素都是等比缩放,实际的显示效果可能不太好。

vw 适配(部分等比缩放)

对于不需要缩放的元素,继续使用px,对于需要缩放的元素,使用vw

  1. 开发者拿到设计稿(假设设计稿尺寸为750px,设计稿的元素标注是基于此宽度标注)
  2. 开始开发,对设计稿的标注进行转换,把px换成vw。比如页面元素字体标注的大小是32px,换成vw(100/750)*32 vw。因为750px = 100vw
  3. 对于需要等比缩放的元素,CSS使用转换后的单位
  4. 对于不需要缩放的元素,比如边框阴影,使用固定单位px

为了开发环境,可以利用自定义css变量

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  <script>
    const WIDTH = 750
    //:root { --width: 0.133333 } 1px等于多少vm ---> 100vw就是750px嘛,那1vm就是100/750
    document.documentElement.style.setProperty('--width', (100 / WIDTH))
  </script>
</head>

注意:

此时不需要设置initial-scale

业务代码

.header {
  font-size: calc(28vw * var(--WIDTH)) // 相当于(28 * WIDTH)px
;
}

rem 适配

  1. 开发者拿到设计稿(假设设计稿尺寸为750px,设计稿的元素标是基于此宽度标注)
  2. 开始开发,对设计稿的标注进行转换
  3. 对于需要等比缩放的元素,CSS使用转换后的单位
  4. 对于不需要缩放的元素,比如边框阴影,使用固定单位px
1

假设设计稿的某个字体大小是40px, 手机屏幕上的字体大小应为420/750*40 = 22.4px(体验好),换算成rem(相对于 html根节点,假设htmlfont-size = 100px)则这个字体大小为0.224 rem

写样式时,对应的字体设置为0.224 rem即可,其他元素尺寸也做换算…如果就这样做的话,那所有的需要缩放的都需要自动动手算一遍,转换思路:看到40px,就应该写40/100=0.4rem, 这样看到就知道多少,就可以不用计算了。此时规定htmlfont-size就不是100px,应该是(420*100)/750 = 56px100这个数是我们自己规定的。

计算思路:

屏幕 设计稿
420px 750px
html 的 font-size 56px 100px

420/x=750/100 ===> x=56px

我们在开发的时候是在750px的设计稿基础上开发。此时页面的htmlfont-size100px,而 rem 就是相对于该值计算,也就是需要缩放的40px,直接写成40/100 = 0.4rem。而在420px的屏幕中的htmlfont-size设置成 56px 就可以。当然100是自己取的值,为了方便计算,可以取其他值,但是不要取1px,浏览器对其会有不同的计算(不准确)

现在要做的就是,根据不同的屏幕宽度,设置htmlfont-size

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  <script>
    const WIDTH = 750 //设计稿尺寸
    const setView = () => {
      document.documentElement.style.fontSize = (100 * screen.width / WIDTH) + 'px'
    }
    setView()
    window.onorientationchange = setView // 屏幕翻转之后重新调用一次
  </script>
</head>

业务代码

// 使用css
.header{
    font-size: .28rem
}
// 使用sass (函数指令)
@function px2rem($px){
    @return $px * 1rem / 100;
}
.header{
    font-size:px2rem(28);
}

推荐阅读:

关于移动端适配,你必须要知道的(超级详细)