引言
最近的工作着重于移动端场景以及大屏场景业务开发,本篇文章主要对这些项目中应用的移动端适配方案进行梳理与总结。
视口配置
在移动端开发场景下,对于视口(<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 方案实现步骤:
监控屏幕宽度的变化,动态设置 html 标签 font-size 的大小(可通过 JavaScript 实现,也可通过媒体查询实现),从而使得随着屏幕大小的变化,元素及文字的大小也随着等比变化。
- JavaScript 实现:通过 JavaScript 监控屏幕宽度的变化,从而动态修改 html 标签的 font-size 值。
媒体查询实现:通过媒体查询根据不同的屏幕宽度(覆盖不同机型的屏幕宽度),设置相应的 html font-size 值。
- 以设计稿宽度作为屏幕宽度标准,设置 html 标签 font-size 初始值为 1px ,则页面中元素单位可直接采用设计稿对应尺寸值(单位为 rem),其他屏幕宽度的 font-size 值为 屏幕宽度 / 设计稿宽度 。
页面中元素的宽高边距以及文字大小等统一采用 rem 作为单位。
- 需要将设计稿的 px 值转换为对应的 rem 值,转换公式:设计稿 px 值 / html 标签 font-size 值 = rem 值
相关插件
- px 转 rem :https://github.com/cuth/postcss-pxtorem
- 动态设置 html 标签 font-size 大小:https://github.com/amfe/lib-flexible
缺点:需要额外引入监控屏幕宽度变化动态更改 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 适配。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。