前言
基本上项目中使用的UI框架都会提供适配方式说明。很贴心~
一、概念
1. 移动端开发
- 原生
App开发(iOS、Android、React Native、uniapp、Flutter等)。 - 小程序开发(原生小程序、
uniapp、Taro等)。 Web页面(移动端Web页面,可以使用浏览器或者webview浏览)。
2. 自适应和响应式
自适应:根据不同的设备屏幕大小来自动调整尺寸、大小。响应式:会随着屏幕实时变动而自动调整,是一种自适应。
3. 视口viewport
在浏览器中可以看到的区域就是视口(viewport)。CSS中的fixed就是相对于视口来进行定位的。
3.1PC端视口
在PC端页面中,不要对视口进行区分,因为布局视口和视觉视口是同一个。
3.2移动端视口
移动端的布局视口是大于视觉视口的。移动端视口分类:
- 布局视口(
layout viewport)
- 默认宽度是
980px。PC端的网页在移动端按照980px的宽度布局盒子和内容,为了完整的显示在页面中,对整个页面进行缩小。 - 相对于
980px布局的视口就是布局视口。
<!-- width:设置布局视口的宽度 -->
<meta name="viewport" content="width=device-width">
- 视觉视口(
visual layout)
- 如果在默认情况下,按照980px显示内容,那么右侧有一部分区域就会无法显示。所以手机端浏览器默认对页面进行缩放以显示到用户的可见区域中。
- 显示在
可见区域的视口,就是视觉视口。
- 理想视口(
ideal layout)
- 默认情况下的布局视口不适合我们的布局。
- 可以对布局视口
进行宽度和缩放的设置,以满足正常在一个移动窗口的布局。 - 就是设置
meta中name为viewport的content属性。
<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单位+动态html的font-size(可用,但已过时)
rem单位是相对于html元素的font-size来设置的。所以只需要修改html的font-size就能达到适配。
2.2.1思路
- 针对
不同的屏幕,设置html不同的font-size。 - 将原
来要设置的尺寸,转化成rem单位。
2.2.2设置动态的font-size
- 方案1:使用媒体查询
- 缺点:只能设置范围,不能达到改变一个
px也实时适配。
- 方案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)
- 方案3:
lib-flexible库
封装的库,作用与方案2相同,可以直接引用。
- 优点:可以限制展示的最大宽度。
- 缺点:已过时,可用新方案(
viewport)替代。
2.2.3rem单位换算
将屏幕宽度10等分。
/* 375设计稿:1rem = (375 / 10)px = 37.5px */
/* 100px = (100 / 37.5)rem = 2.6667rem */
- 方案1:手动计算(麻烦)
- 方案2:
less混入(麻烦) - 方案3:
postcss-pxtorem插件(推荐项目中使用)
- 如实写px,打包时自动转化。
- 以vant项目为例。
- 方案4:
VSCode插件(开发中可用)
- 使用
px to rem & rpx & vw (cssrem)插件,在编写代码时自动转化。 - 缺点:要自己配置
Root Font Size为设计稿宽度/10。
一句话总结:动态改变参照物(font-size)的尺寸。
2.3.vw单位(推荐)
viewport当前的兼容性已经很好了,可以使用。
vw相对于rem的优势:
- 不需要去计算
html的font-size大小,也不需要设置。 - 所以不会因为设置
html的font-size大小而给body再设置一个font-size(防止继承)。 - 不用担心因为某些原因
html的font-size尺寸被篡改,造成页面尺寸混乱。 vw比rem更加语义化,1vw是1/100的viewport大小。- 具备
rem之前的优点。
- 缺点:
无法限制最大宽度。只要视口宽度一直改变,内容展示也会一直跟着变。(但是项目一般不考虑这个问题)
2.3.1思路
- 将原
来要设置的尺寸,转化成vw单位。
2.3.2vw单位换算
屏幕的宽默认为100vw,即把屏幕宽度100等分。
/* 375设计稿:1vw = (375 / 100)px = 3.75px */
/* 100px = (100 / 3.75)vw = 26.66vw */
- 方案1:手动计算(麻烦)
- 方案2:
less混入(麻烦) - 方案3:
## postcss-px-to-viewport-8-plugin插件(推荐项目中使用)
- 如实写px,打包时自动转化。
- 以vant项目为例。
- 方案4:
VSCode插件(开发中可用)
- 使用
px to rem & rpx & vw (cssrem)插件,在编写代码时自动转化。 - 缺点:要自己配置
Vw Design为设计稿宽度。
2.4.flex弹性布局(推荐)
TODO待完善
总结
如果是新建项目,建议用vw做适配。项目使用对应UI组件库(比如Vant)的提供的适配方式。如果是老项目,看看是用rem还是vm的方式,本地编辑器(VSCode)使用插件(px to rem & rpx & vw (cssrem))配合开发进行单位转换。