移动端适配方案总结

Posted 巴拉拉L

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移动端适配方案总结相关的知识,希望对你有一定的参考价值。

目录

一、背景介绍

1.1 为什么要进行移动端适配

移动端设备的尺寸很多,而UI设计稿一般只会基于一个尺寸(一般是750px)进行设计。假如开发人员完全基于该设计稿进行开发,就会出现一种现象,在不同尺寸的设备上,页面的展示效果各不相同,甚至可能出现布局错乱或者出现横向滚动条等情况。因此,开发人员就需要考虑如何让页面内容能够自适应设备尺寸,在设备尺寸较大时内容大一些,设备尺寸小的时候内容也能缩小,让页面在不同的设备尺寸下尽量呈现一致的展示效果。

1.2 移动端适配方案

目前流行的移动端适配方案有两种,rem和viewport,由于viewport单位得到众多浏览器的兼容,现在更多的人推荐使用viewport方案来解决移动端适配问题。下面将对这两个方案做一个大致的介绍。

二、rem方案

2.1 什么是rem

rem是一个相对于页面根元素html的font-size的一个单位,举个例子,假如设置了根元素html的font-size为18px,那么,1rem 等于 18px。由此可知,rem的大小是会随着根元素html的font-size的改变而改变的。rem方案就是利用了这一点,根据不同的屏幕尺寸,来设置不同的根元素html的font-size的大小,以此来达到适配不同屏幕尺寸的目的。

2.2 怎么根据屏幕尺寸设置根元素html的font-size

我们可以使用手淘的amfe-flexible插件,该插件会根据不同设备的屏幕宽度来设置font-size值,下面来简单看一下其实现原理。以下代码是该插件源码的一部分,可以看到,它先是获取了设备宽度,然后除以10。这里大概意思是,将设备宽度分为10等份,然后将一等份的大小作为html元素的font-size值,也就是说1rem就会等于设备的1等份大小(前面说了1rem等于html元素的font-size值)。

// ...
  function setRemUnit () 
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  
// ...

现在举个例子,750px设计稿下,divA的宽度为50px,在具体开发中,divA的宽度应该是多少rem呢?在写divA的宽度时,我们需要自行进行计算,将其rem值设为x,代入该式子x:50=1:75,得出x≈0.67rem,所以,我们这样设置divA的宽度:

.divA 
  width: 0.67rem;

可以看出,将设计稿上的px值转换为rem的过程其实是比较繁琐的,接下来介绍下一个能够自动将px转为rem的插件。

2.3 postcss-pxtorem

postcss-pxtorem是一个能将px转换为rem的工具,这样我们在开发过程中只需要参照设计稿,使用px单位进行开发,由该工具帮我们转换成rem单位即可。只需要在postcss.config.js中进行如下配置:

module.exports = 
  "plugins": 
    "postcss-pxtorem": 
      rootValue: 75, // 根据设计图尺寸写,设计图是750,就写75
      propList: ['*'] // 需要被转换的属性
    
  

如果是使用vant作为移动端开发的组件库,那么就需要注意,vant是基于375写的,而我们开发的设计稿大多750px。所以rootValue设置为75的话,vant的样式就小了一半。通过查阅postcss-pxtorem官网可以知道,rootValue的值可以是number/function,当它是函数的时候,postcss-pxtorem处理每个css文件的时候都会来调用这个函数,且被处理的css文件的相关信息会通过参数形式传递给该函数。因此,我们可以判断是vant文件的样式,还是我们的样式,来决定rootValue的大小。

改写postcss.config.js文件:

module.exports = 
  "plugins": 
    "postcss-pxtorem": 
      rootValue( file ) 
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      ,
      propList: ['*'] // 需要被转换的属性
    
  

三、viewport方案

3.1 什么是viewport方案

通常viewport是指视窗、视口,即浏览器用来显示网页的那部分区域。在移动端开发中,我们希望页面宽度和设备宽度一致,并把这个viewport称为ideal viewport(理想视口)。我们设置public/index.html添加viewport元数据标签,就是为了得到一个ideal viewport。

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

viewport方案即是使用vw/vh作为样式单位。vw、vh将viewport分成了一百等份,1vw等于视口1%的宽度,1vh等于视口1%的高度。当我们的设计稿是750px时,1vw就等于7.5px。还是用之前那个例子,750px设计稿下,divA的宽度为50px,使用vw作为样式单位,divA的宽度是多少vw呢?还是将divA的宽度设置x vw,代入x:50 = 1:7.5,得到x≈6.67vw。

可以感受到,自行计算的过程相当影响开发进度。所以我们引入了postcss-px-to-viewport插件。

3.2 postcss-px-to-viewport

postcss-px-to-viewport是一个将px单位转换为视口单位(一般就是vw)的 PostCSS 插件。这样我们在开发过程中只需要参照设计稿,使用px单位进行开发,由该工具帮我们转换成vw单位即可。只需要在postcss.config.js中进行如下配置,同样地,使用vant组件库的情况下,需要做兼容处理。

module.exports = ( file ) => 
  const vwUnit = file && file.indexOf('vant') !== -1 ? 375 : 750;
  return 
    plugins: 
      'postcss-px-to-viewport': 
        viewportWidth: vwUnit, // 设计稿的宽度
        unitPrecision: 5, // 转换后的位数,即小数点位数
        viewportUnit: 'vw', // 转换成的视窗单位
        propList: ['*'], // 要进行转换的属性,如果某个属性不进行转换,只需在其前加个“!”即可
        selectorBlackList: [], // 不进行转换的选择器
        minPixelValue: 1, // 小于或等于1px则不进行转换
        mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      ,
    ,
  ;
;

四、总结(如果只想看实现步骤可跳过前面直接看本节)

4.1 rem方案实现步骤总结

  1. 安装插件
npm install amfe-flexible --save
npm install postcss-pxtorem --save-dev
  1. 在main.js中引入amfe-flexible
import 'amfe-flexible';
  1. 在postcss.config.js文件中配置postcss-pxtorem
module.exports = 
  "plugins": 
    "postcss-pxtorem": 
      rootValue( file ) 
        return file.indexOf('vant') !== -1 ? 37.5 : 75;
      ,
      propList: ['*'] // 需要被转换的属性
    
  

  1. public/index.html添加viewport元数据标签,使页面宽度和设备宽度一致
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

<!--
含义如下:
* width=device-width:视口宽度和设备保持一致
* initial-scale=1:视口的默认缩放比例1.0
* maximum-scale=1:最大缩放比例1.0
* minimum-scale=1:最小缩放比例1.0
* user-scalable=no:不允许用户自行缩放
-->
  1. 执行上述步骤之后,就可以使用px进行开发了,在页面控制台可以看到,px单位自动被转换成了rem单位。


4.2 viewport方案实现步骤总结

  1. public/index.html添加viewport元数据标签,使页面宽度和设备宽度一致
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  1. 安装插件
npm install postcss-px-to-viewport --save-dev
  1. 在postcss.config.js文件中配置postcss-px-to-viewport
module.exports = ( file ) => 
  const vwUnit = file && file.indexOf('vant') !== -1 ? 375 : 750;
  return 
    plugins: 
      'postcss-px-to-viewport': 
        viewportWidth: vwUnit, // 设计稿的宽度
        unitPrecision: 5, // 转换后的位数,即小数点位数
        viewportUnit: 'vw', // 转换成的视窗单位
        propList: ['*'], // 要进行转换的属性,如果某个属性不进行转换,只需在其前加个“!”即可
        selectorBlackList: [], // 不进行转换的选择器
        minPixelValue: 1, // 小于或等于1px则不进行转换
        mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
      ,
    ,
  ;
;
  1. 执行上述步骤之后,就可以使用px进行开发了,在页面控制台可以看到,px单位自动被转换成了vw单位。


五、参考链接

移动端开发适配总结

移动端开发适配2种方案总结

针对移动端适配的方案~

一: 第一种方案是:所有的单位使用rem来适配;
首先在页面上设置html的font-size的大小;如下我项目中的设置:

html { font-size: 100px; }
@media(min-width: 320px) { html { font-size: 100px; } }
@media(min-width: 360px) { html { font-size: 112.5px; } }
@media(min-width: 400px) { html { font-size: 125px; } }
@media(min-width: 640px) { html { font-size: 200px; } }

html的默认字体大小为100px;是针对于320px来设置的,那么在360px,400px,640px下都需要等比例缩放;
计算公式为: 320px/100 = 360 / x; 那么 x = (360*100 / 320) px; 其他的等比例缩放也是这个意思;
那么设计师给的设计稿给我们的都是默认640px的设计稿;因此我们可以知道font-size:200px; 因此我们可以设置此倍率为200;想px转化为rem的话,
只要知道设计稿多少像素,比如图片的高度是500px;我们需要转换rem的话,计算公式如下:rem = (500 / 200) rem; 其他的属性也是一个意思;比如font-size,margin, padding, 等等属性都是这样计算的 即可转化为rem;我们使用简单的less预编译语言进行计算即可;
比如想保留2位小数;可以如下写 xx = round(500rem/200,2);

二:第二种方案是:纯碎使用px作为单位;(css3媒体查询如下:)

/* 对于400-450按照400px来计算 */
@media (min-width: 400px) and (max-width:450px){
/* 640/400 = 1.6*/ 
@multiple: 1.6;
.mixin(@multiple);
/* 下面可以写一些私有css属性覆盖掉 */

}
/* 对于360-399按照360px来计算 */
@media (min-width: 360px) and (max-width:399px){
/* 640/360 = 1.78 */ 
@multiple: 1.78;
.mixin(@multiple);
/* 下面可以写一些私有css属性覆盖掉 */
}
/* 对于320-359按照320px来计算 */
@media (min-width: 320px) and (max-width:359px){
/* 640/320 = 2*/ 
@multiple: 2;
.mixin(@multiple);
/* 下面可以写一些私有css属性覆盖掉 */
}

/* 下面的mixin函数是使用less预编译语言的,里面需要使用到round方法自动计算各个值 */
.mixin(@multiple){
// 比如高度为500px的话,那么计算公式如下:
height: round(500px / @multiple,2);
// 下面其他的属性值也是一个意思的,设计稿给的多少像素的话,就写多少像素,然后进行计算即可;
}

其他的不需要计算的属性可以写在函数外面,这样就有一个缺点,就是你不写在外面,都写在mixin函数里面的话,那么在每次调用mixin函数内都会生成
一份代码;代码重复了;如果我不写在里面的话,在不需要计算的样式都写在外面的话,那么假如很多类的属性有需要计算的,有不需要计算的,那么就会把
一个css样式分成2份写,对于代码维护不太友好;因此如果项目中能使用rem的话,尽量建议使用第一种方案,使用rem作为单位来适配移动端开发;
不过这两种方案都可以达到适配效果~

使用rem作为单位来对手机适配的demo如下:

rem适配方案参考

 如上git代码已经放了demo,我们可以通过git 克隆下来即可:

如: git clone https://github.com/tugenhua0707/remAdapter.git

然后进入使用命令进入该目录后;在本地取个服务器可以运行命令 gulp server -d ;过一些时间会在本地上开启一个服务器;如:http://localhost:3000/

但是这样是访问不到页面的;因为我gulpfile.js代码全部打包到build文件夹下:比如项目打包后的路径:

build 

   css

   html

   images

   js

因此我们可以在 http://localhost:3000/build/html/ 即可访问到index.html了;同时我们可以打开src源文件下的html下的index.html;可以看到 对应css

<link type="text/css" rel="stylesheet" href="@@@[email protected]@@/css/index.css" />

image图片 使用 @@@[email protected]@@/images/heart.png 这样的路径来引入的;及js文件引入也是通过 @@@[email protected]@@ 作为前缀来引入路径的;这样使用变量做的好处是 可以通过判断是线上环境还是开发环境,如果是开发环境的话 @@@[email protected]@@ 在打包后,会自动替换成 http://localhost:3000/build 这样的,对于线上的环境 可以根据自己的项目的需要替换成响应的路径即可;这些配置都在gulpfile.js内可以看得到,使用了gulp-replace插件进行替换;

同时页面使用了browser-sync插件,可以实时监听html,css,js动态改变,只需要按ctrl+s保存操作,页面会自动刷新;

也支持js的模块化的加载依赖文件,使用了browserify插件进行js模块化加载;

以上是关于移动端适配方案总结的主要内容,如果未能解决你的问题,请参考以下文章

前端移动端适配 - 媒体查询适配方案

前端开发知识之前端移动端适配总结

前端适配

前端开发——移动端及响应式布局解决办法总结(适配)

前端开发——移动端及响应式布局解决办法总结(适配)

移动端适配方案总结