date:
updated:

整理移动端适配常见问题


移动端开发常用单位

px (pixel) 像素

px 是一个虚拟长度单位, 其大小取决于设备, 比如在4k屏幕上的1个像素小的难以用肉眼分辨, 而在古老电子显示器上, 一个像素可能有一个芝麻那么大

在移动端上显示时, css 的 1px 会被渲染为一个逻辑像素, 即下面的 dp;

在某些设备上(比如苹果的笔记本), 本身具有超过1080p的分辨率, 但是实际会显示小于1080p的逻辑像素, 因此在普通电脑上1080p显示正常的网站, 如果没有响应式的设计, 在苹果电脑上可能会崩坏

DP (Device Pixels) 或 DIP(Device Independent Pixels) 设备独立像素

DP表示设备的逻辑像素, Chrome 上的设备开发模式显示的像素即是 DP

移动设备会将1px 渲染到1dp 上, 即css 的1px 相当于设备的一个逻辑像素

在某些手机上, 用户可以自定义手机的dp, 要做移动端适配防不胜防

DPR (Device Pixel ratio) 设备像素比

物理像素和设备独立像素的比值, 比如iphone6 的 DPR 是2, 其逻辑分辨率是 375 * 667, 但手机实际的分辨率是 750 * 1334, 因此会将css的1px渲染为2个物理像素

比如, 设计稿按照 iphone6 750 * 1334 分辨率来做设计, 输出二倍图, 前端同学把图片缩放一倍即为实际设计尺寸

当然,上面的规则也有例外, iPhone6、7、8Plus的实际物理像素是 1080x1920,在开发者工具中我们可以看到:它的设备独立像素是 414x736,设备像素比为 3,设备独立像素和设备像素比的乘积并不等于 1080x1920,而是等于 1242x2208。
实际上,手机会自动把 1242x2208个像素点塞进 1080*1920个物理像素点来渲染,我们不用关心这个过程,而 1242x2208被称为屏幕的 设计像素。我们开发过程中也是以这个 设计像素为准。
在 web中,浏览器为我们提供了 window.devicePixelRatio来帮助我们获取 dpr。
在 css中,可以使用媒体查询 min-device-pixel-ratio,区分 dpr: @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }

某些苹果笔记本上, 实际分辨率是25601600, 但默认分辨率是1280800, 相当于DPR=2, 因此设计pc端页面时以1920*1080为标准的话会有一定的局限性

PPI (Pixel Per Inch) 每英寸包含的像素

反映了屏幕的清晰度, 对选购屏幕很重要, 但对开发来说没有用处

DPI (Dot Per Inch) 每英寸包含的点

点是一个抽象概念, 这个术语描述的和 PPI 相似, 这个点有时指像素, 有时指操作系统的抽象像素, 在不同环境下指代不同

pt (point) 磅

pt 是一个物理长度, 1pt = 1/72 英寸, px = 1 / dpi 英寸, pt = px * dpi / 72
window 下的 dpi 是 96, 1pt = 4 / 3 pt; apple 系统下默认 dpi 是 72, 1pt = 1px
这一套理论看起来天衣无缝, 但总觉得有哪里不对, 毕竟时代变了, pt指代的东西也不同了

pt在现代浏览器中并不是严格的物理长度, 我用手机比对电脑屏幕上相同pt的div, 其物理大小不一致, 或许pt 只在打印时能够体现它固定大小的功能吧(我又没有打印机, 怎么知道)

一个长度为250pt的div, 在电脑上显示为333px, 在安卓手机上也是333px, 在苹果笔记本上还是333px, 苹果手机???

其实现在, pt 更多地被认为是ios的开发单位, 与安卓设备的 dp 相当, 都是代表了屏幕的逻辑像素参考文章, 只是开发安卓和pc端网页时, 几乎很少使用pt作为单位而是px, css 1px 对应 安卓设备的 1dp

使用苹果产品做设计的同学总是喜欢用pt作为单位, 毕竟 1pt = 1px, 但在win和安卓上就不一样了, 当看见以pt为单位的设计图标注时, 要注意转换为px使用

因此, 在css中尽量不要使用pt作为单位

em rem

都是基于 font-size 的尺寸单位, 不同的是 rem 是基于HTML根元素, 而em是基于当前元素

普通浏览器默认 font-size 为16px, 因此1em = 16px

em 单位常用与页面自适应, 比如秀米的营销页面会在 body 设置一个自动变化的 font-size, 页面使用em布局

vw vh

基于 window.innerWidth 和 window.innerHeight 将屏幕划分为100份, 每份就是 1vh 或 1vw

使用这个单位最好禁止用户缩放页面, 因为用 vw 定义的元素不受缩放的影响, 和其他非 vw 单位并存时, 就会发生不一致的变化, 导致页面崩坏。因为 pc 浏览器无法阻止用户缩放, 因此要避免在pc端的网站上混用vw。

由于 vw 和 vh 的大小完全取决于设备, 因此很难落实设计稿中的指定尺寸, 除非设计师能够基于 vw 和 vh 这种基于百分比的方式来做设计图。前端技术的发展对设计的要求越来越高, 在不同的设备上如何实现合乎设计的页面, 需要前端和设计更多的沟通。

论外 小程序提供的单位rpx

微信小程序中推荐你使用rpx作为单位, 小程序把所有屏幕宽度划分成750份, 所以在任何设备上, 宽度都是750rpx

Retina Display 视网膜屏幕

由苹果公司提出的概念, 意思是正常的观看距离内人眼不能分辨出单独的像素

比如psp就很难称之为视网膜屏幕, 其分辨率只有480×272, 以至于你在正常打游戏的时候总能看到大颗粒像素, 因此分辨率是视网膜屏幕的重要指标

正常的视距则是视网膜屏幕的另一个指标, 理论上只要视距足够大, 所有的屏幕都是视网膜屏幕, 比如你距离1米看psp也看不见大颗粒像素

0202年的今天, 大多数手机都符合这个指标了, 但是如果按照手机1080p的分辨率来说, 显示1:1的像素就会显得非常小, 所以就有了DPR, 规定一个逻辑像素等于多少个物理像素, 用多个物理像素来展示一个逻辑像素, 使得以前和未来的手机虽然分辨率差距巨大, 但用户观感基本上没有变化

设置meta标签

为了防止用户对页面进行缩放导致页面变得奇怪, 有必要限制用户对页面的缩放

1
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">

安全区域

随着 iphoneX 的出现, 给移动端适配带来了更多的挑战(ma fan), 比如顶端的刘海, 底部的黑条, 四周的圆角。如果不做适配,可能存在小黑条遮挡页面最底部内容的情况

viewport-fit 规定安全区

1
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

iOS11新增了两个 CSS函数 env、constant,用于设定安全区域与边界的距离, 这两个函数需要上面的mata标签才能生效, 只是设置mata标签而不使用这两个函数同样没有任何作用

这两个函数设配的ios不一样, 最好两个都写上 参考

1
2
3
4
5
6
7
8
# 具体效果如何我也无法做测试,毕竟我没有iphonex
body {
padding:
env(safe-area-inset-top, 20px)
env(safe-area-inset-right, 20px)
env(safe-area-inset-bottom, 20px)
env(safe-area-inset-left, 20px);
}

安卓机也会给我们带来不少惊喜(xia), 比如底部虚拟导航栏占用了屏幕高度, 各种浏览器的顶栏占用屏幕高度等等, 屏幕变得越来越长, 设计一屏滚动页面越来越艰难

留意顶栏高度

ios顶栏高度约为44px, 在设计过程中应注意

图片模糊问题

我们平时使用的图片大多数都属于位图( png、jpg…),位图由一个个像素点构成的,每个像素都具有特定的位置和颜色值。理论上,位图的每个像素对应在屏幕上使用一个物理像素来渲染,才能达到最佳的显示效果。

而在 dpr>1的屏幕上,位图的一个像素可能由多个物理像素来渲染,然而这些物理像素点并不能被准确的分配上对应位图像素的颜色,只能取近似值,所以相同的图片在 dpr>1的屏幕上就会模糊

于是我们就需要二倍图(@2x) 或三倍图, 我们将其css大小设置为原来的二分之一, 但显示到设备上时, 其图像的清晰度能够很好地还原

但是有的设备要求二倍图, 有的设备要求三倍图, 下面提供三种方法适配(前提是设计能给你那么多图,你也有这么多设备去验证它的效果)

1
2
3
4
5
6
7
8
9
10
// 使用媒体查询来适配 background-image
{默认图片}
@media only screen and (-webkit-min-device-pixel-ratio:2) {使用二倍图}
@media only screen and (-webkit-min-device-pixel-ratio:3) {使用三倍图}

// 使用 image-set
background-image: -webkit-image-set( "conardLi_1x.png" 1x, "conardLi_2x.png" 2x );

// 使用 srcset
<img src="conardLi_1x.png" srcset="conardLi_2x.png 2x, conardLi_3x.png 3x">

响应式和自适应的设计

从设计水平的高度来看, 响应式 > 自适应

自适应和响应式都是为了解决页面在不同的设备上的显示问题, 不同的是, 自适应只有一套样式, 在所有的设备上都是同样的设计, 根据页面宽度不同把页面元素作了不同程度的缩放以适应页面

响应式的一个重要的技术特征是使用了媒体查询, 有多套样式, 根据页面宽度的不同应用不同的样式, 直接影响到某些元素是否存在在页面上, 菜单应该以展开还是收缩的形式展现等, 在不同的设备上有完全不同的体验, 而不是设备更大, 就把元素放大

响应式设计让拥有大分辨率设备的用户能够看到更多的内容, 而不是单纯地把原有的内容放大了显示, 在单位空间内显示相同密度的内容是响应式设计重点

参考文章
https://www.sohu.com/a/318395528_100004247


← Prev 在既有项目中引入 vuetify 的问题 | chrome模拟移动设备-解决白边bug Next →