移动端适配-coderwhy笔记

最近频繁碰到适配问题,于是想系统整理一下,听了coderwhy老师的课,记录一下笔记。

点击进入coderwhy老师视频地址


首先我们需要理解一下基本概念。

移动端开发目前主要包括三类:

· 原生App开发(iOS,Android,RN,uniapp,Flutter等)

· 小程序开发(原生小程序、uniapp等)wxml、wxss、js

· Web页面(移动端的Web页面,可以用浏览器或者webview浏览)

目前移动端设备较多,所以需要对其进行一些适配。

这里有两个概念:

· 自适应:根据不同的设备屏幕大小来自动调整尺寸、大小;

· 响应式:会随着屏幕的实时变动而自动调整,是一种自适应。


1.认识视口viewport

1.1视口的基本概念

在一个浏览器中,我们能看到的区域就是视口;

fixed就是相对于视口来进行定位的;

在PC端的页面中,我们是不需要对视口进行区分,因为我们布局视口和视觉视口是同一个;

但是对于移动端:布局视口和可见视口是不一样的。在默认情况下,移动端的布局视口是大于视觉视口。

所以在移动端,我们可以将视口划分为三种情况:

· 布局视口:默认情况下会按照980px来布局一个页面的盒子和内容,为了完整显示页面,会对整个页面缩小。

· 视觉视口:手机浏览器默认对页面进行缩放以显示到用户的可见区域中,显示在可见区域的视口就是视觉视口。

· 理想视口:通过meta里面的viewport进行设置,以满足正常在一个移动端窗口的布局。

1.2理想视口

我们在默认!会生成的html代码中的viewport一行会起到将视口调整为理想视口的作用,如下:

    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 如果没有下面这行,会按980px的布局视口宽度缩小 -->
    <!-- width:设置布局视口的宽度,device-width就是设备宽度 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

content可以设置多个属性,如下图:


2.移动端适配方案

移动端屏幕尺寸繁多,我们希望在不同的屏幕尺寸展示不同大小,可能的方案:百分比设置、rem单位+动态html的font-size,vw单位,flex的弹性布局。

2.1rem方案

rem参照的是html标签的font-size大小。例如如果html标签的font-size为16px,则2rem为32px;

针对不同的屏幕,设置html不同的font-size;

将原来要设置的尺寸,转换为rem单位。

2.1.1 rem+设置动态的font-size(通过媒体查询)

<!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>Document</title>
    <style>
         /* 设置动态的font-size */
        @media screen and (min-width:320px) {
            html {
                font-size: 20px;
            }
        }
        @media screen and (min-width:375px) {
            html {
                font-size: 24px;
            }
        }
        @media screen and (min-width:414px) {
            html {
                font-size: 28px;
            }
        }
        .box {
            width: 5rem;
            height: 5rem;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <!-- 媒体查询 -->
    <div class="box"></div>

</body>

</html>

缺点:很难维护,要重复写很多代码 

2.1.2 rem+通过js设置font-size

        const htmlEL = document.documentElement
        function setRemUnit() {
            const htmlWidth = htmlEL.clientWidth
            const htmlFontSize = htmlWidth /10
            htmlEL.style.fontSize=htmlFontSize+"px"
        }
        setRemUnit()
        //屏幕尺寸变化,实时修改
        window.addEventListener("resize", setRemUnit)
        //持久化
        window.addEventListener("pageShow",function(e){
         if(e.persisted){
           setRemUnit()
        }
        })

2.1.3使用lib-flexible库

github上搜索lib-flexible即可,引用index.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
    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))

计算rem值(单位换算,less/sass函数)

.pxToRem(@px) {
    result: 1rem*(@px/37.5); //如果设计稿是375px,如果是750px则写75
}

.box {
    width: .pxToRem(100)[result];
    background-color: #ccc;
}

p {
    font-size:.pxToRem(14)[result];
}

 由于 viewport 单位得到众多浏览器的兼容,lib-flexible 这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用 viewport 来替代此方案。

注:也可以在webpack配置postcss-pxtorem插件 

注:vscode的px-to-rem插件也可以

目前更推荐使用的是viewport的两个单位vw,wh。

2.2vw单位

2.2.1vw的优势

在375px屏幕上,1vw=3.75px;如果在450px屏幕上,1vw=4.5px;即:1vw 等于viewport的 1%;

vw只面临一个问题,就是将尺寸换成vw的单位即可。

2.2.3vw的换算

 方案一:手动计算,效率太低,不推荐

 方案二:less/sass函数

@vwUnit:3.75;

.pxToVw(@px){
    result:(@px/@vwUnit)*1vw;
}

.box{
    width:.pxToVw(100)[result];
    height: .pxToVw(100)[result];
}

 方案三:webpack插件 postcss-px-to-viewport-8-plugin。在前端工程化开发中,我们可以借助webpack的工具完成自动的转化;

 方案四:VScode插件px to rem&rpx&vw

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值