草庐IT

移动端适配详解 , 给你解决适配烦恼

玄鱼殇 2023-04-14 原文

试想一下,如果我们只能开发web端,那么移动端的网友由谁来做!那也太悲惨了

所以,这里说的就是如何开发页面到移动端,适配各个手机型号,让页面在手机上跑起来~ 

目录

理解些许概念

1. 开发的种类

2. 两个模糊的概念

3. 认识视口

布局视口 : 

视觉视口 : 

理想视口 : 

适配方案一:百分比设置 (不推荐)

适配方案二:rem + 动态html的font-size

问题一的解决方式:

1 - 媒体查询

2 - JS动态计算

3 - 使用lib-flexible库

问题二的解决方式: 

1 - 手动计算 :

2 - 使用scss的函数或者less的混入来计算

        less文件设置

3 - 使用postcss-pxtorem插件 

        01. 安装

        02. 在postcss.config.js中配置

        03. 这样在页面上我们还是直接写px即可,打包后后自动更改的 

4 - 使用VSCode插件 : px to rem 插件

        01. 下载

        02. 配置

        03. 使用

适配方案三:vw 

1 - 手动计算 :

2 - 使用scss的函数或者less的混入来计算

3 - 使用postcss-px-to-viewport插件

01. 下载

02. 在postcss.config.js中配置

03. 这样在页面上我们还是直接写px即可,打包后后自动更改的 

4 - 使用VSCode插件 : px to rem 插件

适配方案四:flex的弹性布局


理解些许概念

1. 开发的种类

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

  • 原生App开发 ( iOS Android RN uniapp Flutter 等 ) 
  • 小程序开发 ( 原生小程序 uniapp Taro 等 ) 
  • web页面 ( 移动端的web页面 ,可以使用浏览器或者webview浏览,可以内嵌进小程序、app )

2. 两个模糊的概念

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

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

3. 认识视口

概念 : 

  • 在浏览器中,可以看到的区域就是视口
  • fixed就是相对于视口来进行定位的
  • 在pc端的页面中,我们不需要对视口进行区分,因为布局视口和视觉视口是同一个

但是在移动端,不太一样,布局的视口和可见的视口是不太一样的,有三种情况

布局视口 : 

相对于980ox布局的这个视口,默认是980px

视觉视口 : 

默认情况下,按照980px来显示的内容,右侧就会有一大部分区域无法展示,所以手机端浏览器会默认对页面进行缩放用来显示到用户的可见区域

显示在可见区域的这个视口,就是视觉视口

 

理想视口 : 

 当布局视口 === 视觉视口的时候,就称之为理想视口

 那么怎么让他们俩相等呢,视觉视口不能更改(手机频幕怎么改~),但是布局视口可更改:

<!-- 
    这里设置的width就是布局视口的宽度 默认是980px。width=980px
    我们一般会改成device-width,让布局视口等于设备宽度
-->
<meta name="viewport" content="width=device-width">

 完美的配置,个人认为

 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

适配方案有以下四种:

适配方案一:百分比设置 (不推荐)

  • 因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一
  • 在移动端适配中使用时很少的

适配方案二:rem + 动态html的font-size

rem的单位是相对于html元素的font-size来设置的,如果我们需要在不同的屏幕下有不同的尺寸,可以动态的修改html的font-size的值

这样就变成了我们要思考这两个问题

  • 问题一 : 针对不同的屏幕,设置html不同的font-size
  • 问题二 : 讲原来要设置的尺寸,转化成rem单位

问题一的解决方式:

1 - 媒体查询

通过媒体查询来设置不同尺寸范围内的屏幕html的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, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <title>Document</title>
  <style>
    /* 利用css的层叠特性 */
    @media screen and (min-width: 320px) {
      html {
        font-size: 16px;
      }
    }
    @media screen and (min-width: 375px) {
      html {
        font-size: 18px;
      }
    }
    @media screen and (min-width: 414px) {
      html {
        font-size: 20px;
      }
    }
    @media screen and (min-width: 480px) {
      html {
        font-size: 22px;
      }
    }
    .box {
      width: 5rem;
      height: 5rem;
      background-color: skyblue;
    }
  </style>
</head>

<body>
  <div class="box"></div>
</body>

</html>

2 - JS动态计算

1. 根据html的宽度计算出font-size的大小,并设置到html上

2. 监听页面宽度的实时变化,重新设置font-size到html上

<!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, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 5rem;
      height: 5rem;
      background-color: skyblue;
    }
  </style>
</head>

<body>
  <div class="box"></div>

  <script>
    // 拿到html元素
    const htmlDom = document.documentElement
    // 改变的函数
    function serRemFontSize() {
      // 拿到屏幕的宽度
      const htmlWidth = htmlDom.clientWidth
      // 计算fontsize的大小  
      const htmlFontSize = htmlWidth / 10
      // fontsize赋值到html上
      htmlDom.style.fontSize = htmlFontSize + 'px'
      console.log(htmlWidth);
    }
    // 第一次进来时主动调用一下
    serRemFontSize()
    // 实时监听屏幕尺寸改变的函数
    window.addEventListener('resize', serRemFontSize)
    // 监听页面跳转(前进或者后退),重新设置一下
    window.addEventListener('pageshow',function(e){
      if (e.persisted) {
        serRemFontSize()
      }
    })
  </script>
</body>

</html>

3 - 使用lib-flexible库

做的事情时一样的,直接引用即可 lib-flexible

一、
// 先安装
npm i -S amfe-flexible

// 在页面处引用
<script src="./node_modules/amfe-flexible/index.js"></script>


二、找到index.js 文件,打开复制代码下来也可

问题二的解决方式: 

加入设计图是375的,页面上一个元素的宽是100px,那么我们得转换成rem

1 - 手动计算 :

用计算器算。100px / html的font-size  =  100 / 37.5 = 2.66667 

width = 2.66667 rem

2 - 使用scss的函数或者less的混入来计算

        less文件设置

@textColor:#12345678;

.poToRem(@px){
  // 375 -> 37.5   根据设计稿来的  设计稿375px  那就 / 37.5
  result:1rem * (@px / 37.5)
}


// 使用less
.box{
  // 利用混入来设定
  width: .poToRem(100)[result];
  height: .poToRem(100)[result];
}

p{
  font-size: .poToRem(16)[result];
}

3 - 使用postcss-pxtorem插件 

webpack的这个工具,在打包时会自动换算,可以看看我的这个文章webpack 插件

        01. 安装

npm install postcss-pxtorem --save-dev

        02. 在postcss.config.js中配置

module.exports = {
  plugins: [
    require('postcss-preset-env'),
    // 使用这个插件
    require('postcss-pxtorem')({
      rootValue: 37.5, // 设计稿宽度的1/10
      propList: ['*'], // 需要做转化处理的属性,如`hight`、`width`、`margin`等,`*`表示全部
      exclude: /node_modules/i // 忽略的文件
    })
  ]
};

        03. 这样在页面上我们还是直接写px即可,打包后后自动更改的 

4 - 使用VSCode插件 : px to rem 插件

        01. 下载

        02. 配置

点击齿轮⚙️ ,选择扩展设置

        03. 使用

适配方案三:vw 

相对于屏幕视口大小,屏幕宽 = 100vw

<!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, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <title>Document</title>
  <style>
    /* 
      375 =>  1vw = 3.75px
    */
    .box {
      /* 100px 转换单位 */
      /* 100 / 3.75 = 26.667vw */
      width: 26.667vw;
      height: 26.667vw;
      background-color: skyblue;
    }
  </style>
</head>

<body>
  <div class="box"></div>

  </script>
</body>

</html>

注意 : vw 永远相对于视口大小,如果视口很大,那么页面的元素也会很大,没办法设置最大最小值

rem可以,rem可以通过媒体查询,设定最大宽度的font-size 

使用vw 就没有rem的问题一了  只有问题二!!!

1 - 手动计算 :

同上rem计算~

2 - 使用scss的函数或者less的混入来计算

同上rem计算~

3 - 使用postcss-px-to-viewport插件

01. 下载

npm install postcss-px-to-viewport -D

02. 在postcss.config.js中配置

module.exports = {
  plugins: [
    require('postcss-preset-env'),
    // 使用这个插件
    require('postcss-px-to-viewport')({
      unitToConvert: 'px', // 需要转换的单位,默认为"px"
      viewportWidth: 375, // 视窗的宽度,对应pc设计稿的宽度,一般是750
      // viewportHeight: 1080,// 视窗的高度,对应的是我们设计稿的高度
      unitPrecision: 5, // 单位转换后保留的精度
      propList: [
        // 能转化为vw的属性列表, * 代表所有
        '*'
      ],
      viewportUnit: 'vw', // 希望使用的视口单位
      fontViewportUnit: 'vw', // 字体使用的视口单位
      selectorBlackList: ['#abc','ignore','tabbar','tabbar-item'], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。cretae
      minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换 小于或等于'1px'不转换为视窗单位
      mediaQuery: false, // 媒体查询里的单位是否需要转换单位
      replace: true, // 是否直接更换属性值,而不添加备用属性
      exclude: /(\/|\\)(node_modules)(\/|\\)/ // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件  exclude:[/DetailBottomBar/,/TabbarItem/]   //包含DetailBottomBar的文件不需要转化

      // landscape: true, // 是否添加根据landscapeWidth 生成的媒体查询条件
      // landscapeUnit: 'rem', // 横屏时使用的单位
      // landscapeWidth: 5120 // 横屏时使用的视窗宽度(横屏的尺寸为938px)

      /**
       * @keyframes 和 media 查询里的px默认时不转化的,设置mediaQuery : true  则媒体查询里的也会转换px
       * @keyframes 可以暂时手动填写vw单位的转化结果
       */
    })
  ]
};

03. 这样在页面上我们还是直接写px即可,打包后后自动更改的 

4 - 使用VSCode插件 : px to rem 插件

移动端适配主要是以上两种方法,第一种的百分比的用的比较少


适配方案四:flex的弹性布局

我想,大家都懂吧!嗯,肯定懂


 补充 :以下是一些概念,很抽象,虽然不懂也能开发,但是面试可能会考哦~

有关移动端适配详解 , 给你解决适配烦恼的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  3. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  4. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  5. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  6. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  7. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  8. ruby - 为什么这些方法没有解决? - 2

    这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭29天前。给定这段代码:classSomethingattr_accessor:my_variabledefinitialize@my_variable=0enddeffoomy_variable=my_variable+3endends=Something.news.foo我收到这个错误:test.rb:9:in`foo':undefinedmethod`+'fornil:NilClass(NoMethodError)fromtes

  9. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  10. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

随机推荐