移动端适配方案

475 阅读5分钟

前言

基本上项目中使用的UI框架都会提供适配方式说明。很贴心~

一、概念

1. 移动端开发

  • 原生App开发(iOS、Android、React Native、uniapp、Flutter等)。
  • 小程序开发(原生小程序、uniappTaro等)。
  • Web页面(移动端Web页面,可以使用浏览器或者webview浏览)。

2. 自适应和响应式

  • 自适应:根据不同的设备屏幕大小来自动调整尺寸、大小。
  • 响应式:会随着屏幕实时变动而自动调整,是一种自适应。

3. 视口viewport

在浏览器中可以看到的区域就是视口(viewport)。CSS中的fixed就是相对于视口来进行定位的。

3.1PC端视口

PC端页面中,不要对视口进行区分,因为布局视口视觉视口是同一个。

image.png

3.2移动端视口

移动端的布局视口是大于视觉视口的。移动端视口分类:

  1. 布局视口(layout viewport
  • 默认宽度是980px。PC端的网页在移动端按照980px的宽度布局盒子和内容,为了完整的显示在页面中,对整个页面进行缩小。
  • 相对于980px布局的视口就是布局视口
image.png
<!-- width:设置布局视口的宽度 -->
<meta name="viewport" content="width=device-width">
  1. 视觉视口(visual layout
  • 如果在默认情况下,按照980px显示内容,那么右侧有一部分区域就会无法显示。所以手机端浏览器默认对页面进行缩放以显示到用户的可见区域中。
  • 显示在可见区域的视口,就是视觉视口
image.png
  1. 理想视口(ideal layout
  • 默认情况下的布局视口不适合我们的布局。
  • 可以对布局视口进行宽度和缩放的设置,以满足正常在一个移动窗口的布局。
  • 就是设置metanameviewportcontent属性。
image.png
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,viewport-fit=cover">

二、方案

1.适配内容

盒子大小、padding、margin、border、left、font-size等等。

2.方案讨论

2.1百分比设置(不推荐)

  • 不同元素(属性)的百分比值,对应的参照物不同,所以不能统一设置。
  • 所以百分比在移动端适配中使用得比较少

2.2.rem单位+动态htmlfont-size(可用,但已过时)

rem单位是相对于html元素的font-size来设置的。所以只需要修改htmlfont-size就能达到适配。

2.2.1思路

  • 针对不同的屏幕,设置html不同的font-size
  • 将原来要设置的尺寸,转化成rem单位。

2.2.2设置动态的font-size

  1. 方案1:使用媒体查询
  • 缺点:只能设置范围,不能达到改变一个px也实时适配。
  1. 方案2:JavaScript代码动态计算
  • 缺点:功能不齐全。
// 1.获取html元素
const htmlEl = document.documentElement

function setUnit () {
  // 2.获取html宽度(视口宽度)
  const htmlWidth = htmlEl.clientWidth
  // 3.根据宽度计算一个html的font-size大小
  const htmlFontSize = htmlWidth / 10
  // 4.将font-size设置到html上
  htmlEl.style.fontSize = htmlFontSize + 'px'
}
// 保证第一次进来时,可以设置一次font-size
setUnit()
// 当屏幕尺寸发生变化,实时修改html的font-size
window.addEventListener('resize', setUnit)
  1. 方案3:lib-flexible

封装的库,作用与方案2相同,可以直接引用

  • 优点:可以限制展示的最大宽度。
  • 缺点:已过时,可用新方案(viewport)替代。

2.2.3rem单位换算

将屏幕宽度10等分。

/* 375设计稿:1rem = (375 / 10)px = 37.5px */
/* 100px = (100 / 37.5)rem = 2.6667rem */
  1. 方案1:手动计算(麻烦)
  2. 方案2:less混入(麻烦)
  3. 方案3:postcss-pxtorem插件(推荐项目中使用)
  • 如实写px,打包时自动转化。
  • vant项目为例。
  1. 方案4:VSCode插件(开发中可用)
  • 使用px to rem & rpx & vw (cssrem)插件,在编写代码时自动转化。
  • 缺点:要自己配置Root Font Size设计稿宽度/10
image.png

一句话总结:动态改变参照物(font-size)的尺寸。

2.3.vw单位(推荐)

viewport当前的兼容性已经很好了,可以使用。

  1. vw相对于rem的优势:
  • 不需要去计算htmlfont-size大小,也不需要设置。
  • 所以不会因为设置htmlfont-size大小而给body再设置一个font-size(防止继承)。
  • 不用担心因为某些原因htmlfont-size尺寸被篡改,造成页面尺寸混乱。
  • vwrem更加语义化,1vw1/100viewport大小。
  • 具备rem之前的优点。
  1. 缺点:
  • 无法限制最大宽度。只要视口宽度一直改变,内容展示也会一直跟着变。(但是项目一般不考虑这个问题)

2.3.1思路

  • 将原来要设置的尺寸,转化成vw单位。

2.3.2vw单位换算

屏幕的宽默认为100vw,即把屏幕宽度100等分。

/* 375设计稿:1vw = (375 / 100)px = 3.75px */
/* 100px = (100 / 3.75)vw = 26.66vw */
  1. 方案1:手动计算(麻烦)
  2. 方案2:less混入(麻烦)
  3. 方案3:## postcss-px-to-viewport-8-plugin插件(推荐项目中使用)
  • 如实写px,打包时自动转化。
  • vant项目为例。
  1. 方案4:VSCode插件(开发中可用)
  • 使用px to rem & rpx & vw (cssrem)插件,在编写代码时自动转化。
  • 缺点:要自己配置Vw Design设计稿宽度
image.png

2.4.flex弹性布局(推荐)

TODO待完善

总结

如果是新建项目,建议用vw做适配。项目使用对应UI组件库(比如Vant)的提供的适配方式。如果是老项目,看看是用rem还是vm的方式,本地编辑器(VSCode)使用插件(px to rem & rpx & vw (cssrem))配合开发进行单位转换。

附录

  1. 视频:移动端适配方案
  2. 文章:移动端视口