移动端适配
2026/2/4大约 6 分钟
常规概念
- 物理像素:
屏幕是由固定的像素点(发光点)组成的, 一块屏幕生产出来之后, 物理像素点(分辨率)就固定了 - 逻辑像素:
可以理解逻辑像素就是CSS像素或者参考像素, 是逻辑上抽象的, 不是实际屏幕的物理像素 - DPR:
dpr = 物理像素/逻辑像素, 在某个方向上的比值, 不如dpr=2 ,代表一个逻辑像素, 使用2*2的像素来渲染一个逻辑像素 - PPI:
每英寸的物理像素的密度, 数字越高, 说明物理像素越密集. 公式为 ppi = 对角线像素 / 对角线尺寸
对角线像素 = Math.sqrt(Math.pow(横向分辨率, 2) + Math.pow(纵向分辨率, 2)) - 屏幕物理尺寸 使用尺子量出来的尺寸, 和屏幕的物理像素无关, 就是绝对的尺寸大小
参考像素,逻辑像素,CSS像素
- 定义:
视角度量单位, 在距离阅读者一臂之遥(约 71 厘米或 28 英寸)时,1 像素(px)对应 1/96 英寸的视角 - 参考像素,逻辑像素,CSS像素可以看成是同一个, 单位是px
- 参考像素是视觉角度, 而不是具体的物理尺寸(用尺子量出来的尺寸)
- 比如远处的房子和近处的模型, 虽然大小不同, 但是, 因为远近的关系, 我们看起来是一样大的
- 参考像素的物理尺寸只和观看距离相关, 和屏幕实际的大小, 分辨率都无关系
- 所以在不同的设备上, 比如手机, 平板, 显示屏, 电视上, 因为我们观看距离不同, 所以参考像素的物理大小是不同的, 但是我们会保证, 同样像素的物体, 在不同的观看距离上, 从视觉上看起来大小是相同的, 也就是, 手机观察的距离比较近 所以参考像素的物理尺寸是小于电视或者平板上的参考像素的尺寸的. 但是同为手机, 参考像素是一样大的(因为观看距离相同), 和物理像素无关.也就是, 无论是ppi多大的, 参考像素的尺寸都是一样大的, 只是ppi大的手机屏幕, 一个参考像素对应的物理像素 比较大, 也就是dpi比较大
- 参考像素是视觉角度, 而不是具体的物理尺寸(用尺子量出来的尺寸)
- 为了使同样大小的, 比如12px的字体, 在手机, 平板, 电视上, 看起来一样大(观看距离不同, 实际物理尺寸是不同的)
- 设备无关的抽象层, 开发者只需要关心这个字体显示为12px这么大, 不需要关心是显示在手机, 还是平板, 还是电视上或者同一种设备不同ppi的具体物理尺寸和具体理像素
- 解决高密度(PPI高)屏幕渲染问题
物理像素, 分辨率
- 显示屏是由一个个物理像素点组成的, 也就是屏幕标识的分辨率, 是实际渲染内容的物理像素点, 像素点密度使用ppi表示, 像素点越密集(ppi越高), 屏幕显示元素越清晰
viewport
- 移动端常见设置
// 让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">常见问题
- 不同设备, 比如手机, 平板, 电视, 是如何适配的
- 开发过程中使用CSS像素(参考像素), 也就是同样的12px大小, 在不同屏幕(不同观看距离下)看起来是一样大的, 但是实际大小是不一样的(距离越远, 实际物理尺寸越大), 天然适配
- 由于不同屏幕, 宽度比率不同, 实际物理横向宽度 / 实际参考像素, 得到的结果也是不同的, 也就是, 适配时还是需要考虑换行问题的, 即使是同一种设备(比如手机), 手机的参考像素是相同的, 但是手机横向宽度是不同的, 所以横向能容纳的元素是不同的, 这些都需要考虑换行问题
- 同样物理尺寸的屏幕(比如手机), 分辨率不同(比如高清屏和普通屏)是如何适配的
- 通过dpr进行适配. 在不同的手机上, 由于参考像素的尺寸是固定的, 所以横向的总的CSS像素是可以得到的. 这样总的横向物理像素(横向分辨率)/横向CSS像素(逻辑像素, 参考像素)就是dpr的值, 也就是dpr的值就是一个CSS像素对应dpr个像素点(一个方向上)
- 不同的手机, 通过dpr, 调整1个CSS对应几个物理像素点, 就可以使得同一个CSS大小, 在不同分辨率手机上, 显示的物理大小是一样的
常见移动端适配解决方案
- 我们知道, 逻辑像素, 解决了不同物理大小, 不同分辨率手机屏幕的看起来一样大的问题, 因为看起来一样大的问题, 所以手机屏幕的逻辑像素的实际物理尺寸是一样的. 屏幕实际物理宽度不同, 会导致不同屏幕横向能展示的逻辑像素不同, 会出现不同手机屏幕换行的问题, 如何解决这个问题呢
<!-- 1. 基础Viewport设置(必须) --> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <!-- 2. 全面屏适配 --> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <!-- 3. 安全区域处理 --> <style> .safe-area { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } </style>- rem
- 因为手机屏幕的物理宽度差别不会很大, 也就是宽度的逻辑像素不会相差很大, 我们可以让页面元素在不同的屏幕上进行等比缩放, 达到大屏幕会显示的大一点, 小屏幕会显示的小一点, 而不会出现大屏幕可以显示, 小屏幕换行的问题
- 单位 需要等比缩放的使用rem为单位, 不需要缩放的, 继续使用px为单位
- 设计方式
// 设置根字体大小为 100*屏幕宽度/设计稿宽度 document.documentElement.style.fontSize = 100 * document.documentElement.clientWidth / 设计稿宽度 + 'px'; window.addEventListener('resize', function() { document.documentElement.style.fontSize = 100 * document.documentElement.clientWidth / 设计稿宽度 + 'px'; });- 使用方式 对于375或者750的设计稿, 比如测量出来的width=175px, 只需要设置width=1.75px. 测量出来的值/100就可以等比例缩放了
- rpx 微信小程序独有单位, 规定所有手机屏幕的宽度都是750rpx, 这样出的750设计稿, 可以直接使用rpx单位
rpx的原理和rem一样, 都是等比例放大缩小来适应不同宽度的手机, 达到一致的体验
- rem