移动端适配
主要介绍移动端适配中的一些重要概念和技术方案
各种“像素”
物理像素
又称设备像素,即我们平常主要所说的分辨率的尺寸单位
,例如电脑和手机设备的屏幕分辨率。屏幕是由一个个的物理像素点组成的。例如手机分辨率为1344 X 750
表示手机分别在垂直和水平方向的物理像素点数。一般来说,屏幕的物理像素点数是固定不变的,单位为pt。
CSS像素
又称设备独立像素
,平常写的CSS样式中的px尺寸单位即是CSS像素,而每个设备屏幕也都有自己对应的CSS像素尺寸。
打开Chrome浏览器的移动端调试页面可看到对应页面上方有当前测试设备的相关信息。
这里的375 X 812
表示的就是当前设备的CSS像素。当我们在设计网页时,进行移动页面样式调试,调试的样式尺寸基准就是CSS像素,而非物理像素。即当我们在页面中放一个width=375px,height为812px的div标签时,不考虑其他因素影响,在理想视口下(关于视口的介绍见下方),则它正好可以撑满当前设备整个屏幕。
设备像素比
DPR(Device Pixel Ratio),设备像素比。它描述的是未缩放状态下,物理像素和CSS像素(设备独立像素)的初始比例关系。即表示每1px CSS像素所能包含的物理像素个数。
通常情况下计算公式为DPR = 物理像素 / 设备独立像素(CSS像素)
,通过此公式便可得到CSS像素。
DPR越高,代表屏幕显示的精致程度越高。苹果手机的Retina高清屏则是经典案例,以DPR=2.0为例,则表示把一般的4(即2 X 2)个物理像素点数当作1(1 X 1)个CSS像素点数来用。
虽然DPR越高代表屏幕高清效果越好,但DPR越高会对一些网页显示素材(如图片)的质量(清晰度)要求也会越高。举个常见的比较通俗易懂的例子,进行页面开发时,对于一些图片资源,UI会给我们提供分辨率相对于原始应该在页面上显示的CSS像素大小的2倍,3倍的图片文件。这些图片正是为了兼容DPR为2.0和3.0的设备的。
举例说明
比如我们一个分辨率像素为100 X 100的图片在浏览器上也是设置CSS像素为100px * 100px,在dpr为1的设备上显示没有什么问题。但是如果是DPR=2的设备即水平或垂直方向上1css像素对应2个物理像素,则水平和垂直方向上分别只需要100/2=50个css像素就可标准清晰地显示该图片,但此时如果该图片依然设置100px * 100px的CSS像素,那么实际效果图片的每一个物理像素都会被拉伸成2个物理像素(1css像素)以便能撑满100px的CSS像素,所以图片显示效果变模糊一些。这时候使用2倍图(即200 X 200的图片)且CSS像素尺寸设置不变(100px * 100px)便可解决此问题。
苹果手机1px边框线变粗问题
关于移动端经典的1px边框线变粗的问题,其实其真实原因并非网上大多数所说的DPR(即物理像素与CSS像素关系)的原因。DPR只会影响页面的精细程度和高清效果,不会影响CSS像素的尺寸
,如果是DPR的原因,那么为什么2px,3px的边框线不会变粗呢?
UI的750px设计稿中有1px的边框线。当我们采用等比缩放的适配方案(如rem)在375px的移动设备中看的时候,应该是CSS像素0.5px的边框线。然而移动设备大多数最细只能显示1px的CSS像素,此时比例不对了,就会视觉感官上觉得“变粗”。
1px像素问题的核心在于移动设备的最小可显示的CSS像素
,如今最新的IOS版本支持了0.5px的像素。
浏览器视口
移动设备上的视口(学术名称为viewport)就是设备的屏幕上能用来显示我们的网页的那一块区域。浏览器的视口主要分为以下几类:
布局视口
布局视口表示的是整个网页内容布局的矩形区域,页面元素的渲染永远不会超出这个区域
。
一般移动设备的浏览器都默认设置了一个 viewport 元标签,定义一个虚拟的布局视口(layout viewport)
,用于解决早期的页面在手机上显示的问题。 iOS, Android 一般默认都将这个虚拟的布局视口分辨率设置为CSS像素的 980px
,所以 PC 上的网页基本能在手机上呈现,只不过元素看上去很小,所以通常PC的网页在移动设备都是通过手动缩放来控制合适的页面显示大小。
技巧
通常来讲,布局视口的尺寸与页面根元素html标签的CSS像素大小是一致的。所以js一般可通过document.documentElement.clientWidth/clientHeight
来获取。(这个值不会因为html元素本身被设置了width或内部元素宽度超出当前视口宽度而变化)
视觉视口
又称可见视口,它表示的是布局视口中在当前设备中可见
的矩形区域的那一部分。
可见视口的尺寸大小会随着用户的手动缩放页面而变化
。放大时,可见的页面CSS像素减少;缩小时,可见的页面CSS像素增多。
理想视口
布局视口提供的默认视口尺寸并不是一个兼容多种设备的智能视口,所以提出了一个理想视口的概念。
通过在HTML中的头部head标签中添加关于viewport的meta标签可进行视口设置:
<meta name="viewport" content="width=device-width, user-scalable=yes,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
属性 | 取值范围 | 作用 |
---|---|---|
width | 正整数或device-width | 定义视口的宽度,单位为CSS像素 |
height | 正整数或device-height | 定义视口的高度,单位为CSS像素,一般不用 |
initial-scale | 0.0-10.0 | 定义初始缩放值 |
minimum-scale | 0.0-10.0 | 定义放大最大比例,它必须小于或等于maximum-scale设置 |
maximum-scale | 0.0-10.0 | 定义缩小最小比例,它必须大于或等于minimum-scale设置 |
user-scalable | yes / no | 定义是否允许用户手动缩放页面,默认值 yes |
上面示例的meta标签代码代表的就是设置了一个理想视口:表示当前布局视口宽度与当前设备的CSS像素宽度一致,且默认不进行缩放。
这样设置后,可实现页面在所有设备上默认布局视口宽度与设备屏幕宽度一致的自适应效果
。
注意
- viewport的meta标签的设置
只对移动端生效
,不影响PC端视口。PC端视口大小一般随浏览器窗口的大小变化而变化。 - 如果想兼容移动端查看但又不想写响应式代码,则不要设置viewport=width或者改为设置viewport=固定像素值
- 尽量不要禁用缩放(user-scalable设置为no),避免为视力或行动有障碍的用户带来不便。
适配方案
移动端web的适配方案从根本性质上可分为以下两类:
自适应
自适应(daptsive Web Design),这种适配方案通常来说同一个网站会拥有PC端,移动端两套网页代码(甚至更多)。通常移动端的页面功能和内容可能会相比PC端有所削减。而单纯针对移动端页面,则会表在不同尺寸的手机设备上,页面保持统一效果的等比缩放
的效果。
rem
rem是相对于html根元素的font-size大小的倍数单位。如html的font-size为16px,则2rem代表32px.
rem适配方案的核心实现过程就是根据先设置好的比例关系在CSS样式中使用rem单位,通过监听视口尺寸(即设备分辨率)的变化,动态地改变根元素font-size的大小,从而实现页面元素等比缩放的自适应效果。
vw / vh
vw,vh,vmax,vmin是CSS推出的
视口专属单位
,各单位具体含义如下:- vw : 1vw 等于 视口宽度 的 1%,即100vw等于视口宽度
- vh : 1vh 等于 视口高度 的 1%,即100vh等于视口高度
- vmin : 选取 vw 和 vh 中 较小 的那个
- vmax : 选取 vw 和 vh 中 较大 的那个
通常我们会通过viewport的meta标签将视口设置为理想视口(即width = device-width
)。这样100vw,100vh就分别表示屏幕的宽,高度。这样更加方便计算元素与设计稿的比例关系,使得这些元素能够随视口大小自适应调整。
rem和vw/vh二者往往会组合使用
,下面是我个人推荐的一套基于webpack + vw + rem
而设计的自适应适配方案:
技巧
使用postcss-plugin-px2rem
插件负责自动转换px为rem:
// postcss.config.js
module.exports = {
plugins: {
'postcss-plugin-px2rem': {
rootValue: 100, // px数值/rem数值,即1px转成0.01rem
exclude: /(node_modules)/,
minPixelValue: 1, // 1px以上的生效
selectorBlackList: ['html'],
propBlackList: ['max-width', 'max-height', 'min-width', 'min-height'] //忽略转换的css属性
}
}
};
使用rem方案配合上述px2rem插件,动态更新font-size:
html {
/*750为设计稿基准*/
font-size: calc(100vw / 7.5) !important;
/*这里本应该写 100vw/750px 即750设计稿条件下某元素尺寸是a px,则css代码依然写a px,最终转换成a rem。
但由于px2rem插件中配置的rootValue为100,即最终转换成0.0a rem(也是为了兼容iphone),所以相应的也要改成100vw/ 7.5 */
background-color: #fff;
height: 100%;
}
@media screen and (min-width: 751px) {
/*设置上限值,兼容pc端显示效果*/
html {
font-size: 80px !important;
}
}
此方案通常基于Webpack并配合React或Vue相关框架,最终实现效果为根据UI设计稿尺寸,无需计算比例关系即可实现自适应适配
。
响应式
响应式(Responsive Web Design),这种适配方案通常来说一套代码,多端适用
。
是一种用来为各种分辨率和设备性能优化视觉体验的技术方案。多年前非常流行的Bootstrap就是一套非常好的响应式UI框架。主要通过媒体查询,弹性布局
等手段来为从移动端到PC端由小变大的不同分辨率提供可伸缩性的页面布局效果。同样也会出现不同分辨率下呈现功能内容多少不同的现象。但总体会遵循主要内容永远保留的原则。
响应式由于其需要考虑的方面很多,其布局设计上在很大程度上依赖媒体查询
。以下是一段媒体查询代码示例:
@media screen and (max-width: 300px) {
body {
background-color:lightblue;
}
}
这段css代码表示如果当前视口宽度小于 300 CSS像素时,body元素则修改背景颜色(background-color)为lightblue
媒体查询注意点
max-device-width
是真实的设备较短那一边的屏幕CSS像素宽度(固定值不变),而max-width
是当前页面视口的CSS像素宽度,会跟随设备横竖屏切换而变化。
响应式设计特点:
优点:
跨设备兼容性和用户体验良好。
开发维护成本上,相对多套代码会降低很多。
缺点:
开发复杂度提升,需要开发者考虑不同设备下的布局和交互问题。
性能问题,尤其处理大量图片和媒体文件时,需要考虑不同设备下使用不同的图片媒体文件(例如
使用img元素的srcset和sizes属性
),避免流量浪费从而影响加载速率。局限性,响应式不适合一些元素过多的大型门户网或者电商网站,否则需要牺牲设计上一定程度的灵活性。