关于移动端适配的笔记

207 阅读3分钟

移动端适配是内容按照不同屏幕大小自动等比例缩放的一种布局计算方式,一般只在移动端使用。不会改变布局!

移动端适配:

  • rem:目前多数企业在用的解决方案
  • vw/vh:未来的解决方案【b站、天猫用这个】

rem适配布局有两种方案,一种是rem+媒体查询+less ,一种是使用flexible.js。目标:能够使用rem单位设置网页元素的尺寸,实现:屏幕宽度不同,网页元素尺寸不同(等比缩放)。

一、rem

rem( root em )单位:

  • 相对单位
  • rem单位是相对于HTML标签[根标签]的字号计算结果
  • 1rem = 1HTML字号大小
/* 1rem = 1html标签字号大小 */
        html {
            font-size: 20px;
        }
        
        .box {
            width: 5rem;   //100px
            height: 3rem;  //60px
        }

方案1:rem+媒体查询+less

原理

1、让一些不能等比自适应的元素,达到当设备尺寸发生改变时等比例适配当前设备

2、使用媒体查询根据不同设备比例设置html的字体大小,然后页面元素使用rem做尺寸单位,当html字体大小变化,元素尺寸也发生变化,从而达到等比例缩放的适配。

技术

媒体查询( Media Query )是CSS3新语法,它能够检测视口的宽度,可以针对不同的屏幕尺寸、媒体类型设置不同的样式,重置浏览器大小的过程中,会根据浏览器的宽高重新渲染,目前很多苹果手机、安卓手机、平板等设备都用得到多媒体查询。

目前rem布局方案中,将网页等分成10分,html标签的字号为视口宽度的1/10

rem单位尺寸计算:1.确定基准根字号(1/10视口宽度) 2.rem单位的尺寸 = px单位数值/基准根字号

/* 使用媒体查询, 根据不同的视口宽度, 设置不同的根字号 */
        @media (width:375px) {
            html {
                font-size: 37.5px;
            }
        }

        @media (width:320px) {
            html {
                font-size: 32px;
            }
        }

方案2:rem+flexible.js

flexible.js是一个用来适配移动端的js框架。 核心原理就是根据不同的视口宽度给网页中html根节点设置不同的font-size。引入js文件即可。
引入的时候用<script src='../flexible.js'>引入

(function flexible (window, document) {
  var docEl = document.documentElement
  var dpr = window.devicePixelRatio || 1

  // adjust body font size
  function setBodyFontSize () {
    if (document.body) {
      document.body.style.fontSize = (12 * dpr) + 'px'
    }
    else {
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize
  window.addEventListener('resize', setRemUnit)
  window.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports 检测是否支持0.5像素,解决1px在高清屏多像素问题,需要css的配合。
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('div')
    testElement.style.border = '.5px solid transparent'
    fakeBody.appendChild(testElement)
    docEl.appendChild(fakeBody)
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines')
    }
    docEl.removeChild(fakeBody)
  }
}(window, document))

二、vw /vh

使用vw单位设置网页元素的尺寸

  • 相对单位
  • 相对于视口的尺寸计算结果
  • vw:viewport width 【1vw=1/100视口宽度】
  • vw:viewport height【1vh=1/100视口高度】
/* 1. vw = 1/100视口宽度 */
        /* .box {
            width: 50vw;
            height: 30vw;
            background-color: pink;
        } */

        /* 2. vh = 1/100视口高度 */
        .box {
            width: 50vh;
            height: 30vh;
            background-color: pink;
        }

截屏2022-09-20 下午9.34.53.png

// 基于375px * 667px的设计稿
// 68px * 29px  -- vw
// 在less文件中可用除法,会自动转为css文件
.box {
    width: (68 / 3.75vw);
    height: (29 / 3.75vw);
}
 // vh
.box2 { 
    width: (68 / 6.67vh);
    height: (29 / 6.67vh);
}

移动端适配流程

  1. 在head 设置width=device-width的viewport

  2. 在css中使用px

  3. 在适当的场景使用flex布局,或者配合vw进行自适应

  4. 在跨设备类型的时候(pc <-> 手机 <-> 平板)使用媒体查询

  5. 在跨设备类型如果交互差异太大的情况,考虑分开项目开发