引言

最近的工作着重于移动端场景以及大屏场景业务开发,本篇文章主要对这些项目中应用的移动端适配方案进行梳理与总结。

视口配置

在移动端开发场景下,对于视口(<meta name="viewport” ... />)的推荐初始配置如下

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
  • width=device-width —— 使当前视口宽度与设备宽度一致
  • user-scalable=no —— 禁止用户进行缩放操作
  • initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0 —— 将各个缩放比均设置为1.0

高清方案

DPR(设备像素比)

物理像素、逻辑像素以及设备像素比。
为什么会出现以上概念?因为现在手机屏幕普遍采用了视网膜屏技术即用多个物理像素来渲染一个逻辑像素从而使屏幕显示效果更佳清晰细腻
物理像素(设备像素)指设备屏幕实际存在的像素点即设备实际分辨率
逻辑像素(CSS 像素)指设备系统设置的像素,对开发者而言,是在实际开发中使用的像素(系统设置的像素),在 Chrome 开发者面板可查看到设备的逻辑像素
设备像素比(DPR):指在某一方向(即宽度方向或高度方向) 物理像素与逻辑像素之比(物理像素/逻辑像素),DPR 越高,意味着设备显示效果越清晰细腻

以 iPhone12 Pro 为例:

  • 物理像素: 在宽度方向拥有 1170 个像素点,在高度方向拥有 2532 个像素点,即尺寸为 1170*2532 。
  • 逻辑像素: 在 Chrome 开发者工具以 iPhone12 Pro 为当前设备时,对应的尺寸为 390*844 。
  • 即设备像素比为 1170 / 390 = 3

图片高清方案

由于设备像素比的出现,在开发中,为了保证图片的显示清晰度,需要在不同的 DPR 下加载不同尺寸的图片(多倍图)。

在 JavaScript 中设备像素比可通过 window.devicePixelRatio 取得

在 CSS 中,设备像素比可通过 -webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio 等取得。以上属性需要在媒体查询中使用用于修改 background-imag,且只支持 webkit 内核的浏览器

@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
  
}

@media only screen and (-webkit-min-device-pixel-ratio: 3),
only screen and (min-device-pixel-ratio: 3) {

}

1px 边框

当设备 DPR 大于 1,例如 DPR 为 2 时,意味着 1px 在屏幕上实际呈现的效果比 DPR 为 1 设备粗一倍 (这是由于 DPR 2 设备使用了 2 个物理像素渲染了 1 个逻辑像素造成的),导致视觉效果与设计稿预期效果不一致,即使采用了 vw 或 rem 作为 border-width 单位,但大小可能会小于 1px这在各浏览器的兼容性不佳
建议通过伪元素 + transform scale 缩放来实现 1px 边框,具体如下:
创建一个 height:1px 的伪元素,通过 transform:scaleY(0.5) 将其缩小一倍使用绝对定位来决定其为上下边框或左右边框

.scale-1px{
  position: relative;
  border:none;
}
.scale-1px::after{
  content: '';
  position: absolute;
  bottom: 0;
  background: #000;
  width: 100%;
  height: 1px;
  -webkit-transform: scaleY(0.5);
  transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}

等比缩放适配

等比缩放适配方案使得页面中元素大小以及文字大小随着屏幕大小的缩放而等比缩放,具体可通过 rem 、vw 等相对单位来实现。

rem 方案

rem:相对单位,表示相对于 html 标签 font-size 的大小。

rem 方案实现步骤:

  1. 监控屏幕宽度的变化,动态设置 html 标签 font-size 的大小(可通过 JavaScript 实现,也可通过媒体查询实现),从而使得随着屏幕大小的变化,元素及文字的大小也随着等比变化

    • JavaScript 实现:通过 JavaScript 监控屏幕宽度的变化,从而动态修改 html 标签的 font-size 值。
    • 媒体查询实现:通过媒体查询根据不同的屏幕宽度(覆盖不同机型的屏幕宽度),设置相应的 html font-size 值。

      • 以设计稿宽度作为屏幕宽度标准设置 html 标签 font-size 初始值为 1px ,则页面中元素单位可直接采用设计稿对应尺寸值(单位为 rem),其他屏幕宽度的 font-size 值 屏幕宽度 / 设计稿宽度
  2. 页面中元素的宽高边距以及文字大小等统一采用 rem 作为单位

    • 需要将设计稿的 px 值转换为对应的 rem 值,转换公式:设计稿 px 值 / html 标签 font-size 值 = rem 值

相关插件

缺点:需要额外引入监控屏幕宽度变化动态更改 html 标签 font-size 大小的 JavaScript,采用媒体查询也会存在适配的“断层”问题,由于浏览器已支持 vw 单位,推荐使用 vw 方案来代替 rem 方案

vw 方案

vw:相对单位,表示相对当前视口宽度的百分比,1vw 表示当前视口宽度的 1%。
vh:相对单位,表示相对当前视口高度的百分比,1vh 表示当前视口高度的 1%。
vmin:相对单位,表示相对当前视口较小尺寸的百分比,1vmin 表示当前视口较小尺寸的 1%(常在需要横屏适配时使用)。
vmax:相对单位,表示相对当前视口较大尺寸的百分比,1vmax 表示当前视口较大尺寸的 1%。

vw 方案实现步骤
对于元素的宽高边距以及文字大小等统一采用 vw/vmin 作为单位。

以 375px 尺寸设计稿为例,推导 1px 等于多少 vw:
375px / 1px = 100vw / ?vw
?vw = 100 / 375
?vw = 1 / 3.75
即,375px / 1px = 100vw / 1vw / 3.75
1px = 1vw / 3.75

设计稿 px 值转 vw 值公式设计稿相应元素尺寸 / 设计稿宽度 / 100 = vw 值
推荐采用设计稿尺寸进行开发,然后使用 postcss-px-to-viewport 插件实现自动转换即可。

缺点:不支持设置页面的最小宽度和最大宽度,页面元素尺寸仍将随着屏幕变化而变化,即使当前屏幕小于最小宽度或者大于最大宽度。

rem + vw 方案

通过将 rem + vw 方案结合使用,可实现等比缩放适配,同时支持设置页面的最大宽度或最小宽度

实现步骤
设置 html 标签 font-size 值为 vw 值1vw 相当于屏幕宽度的 1%以 750px 设计稿宽度为例

  • 1vw = 750 / 100 = 7.5px
  • 1px = 1vw / 7.5px = 0.133333vw

将 html 标签 font-size 值设为 0.13333vw页面元素及文字的尺寸与设计稿相应元素尺寸保持一致即可单位为 rem)。

html {
  font-size: 0.133333vw;
}
/* 针对PC端,屏幕宽度超过 750px 的情况. */
@media screen and (min-width: 750px) {
  html {
    font-size: 1px;
  }
}
div{
  width:200rem;
  height:150rem;
}

局限性与应用场景

等比放大意味着更大的屏幕无法显示更多的内容,但在某些场景下,用户可能希望在更大的屏幕下能尽可能看到更多的内容
因此,建议在信息流等阅读内容较多的场景下,使用 px + Flex 布局即可对于视觉元素较多的场景下,使用 vw 适配,当需要设置最小宽度或最大宽度的场景时(例如大屏开发场景),采用 rem + vw 适配


hwjfqr
49 声望5 粉丝