rem做移动端适配(2020.12.06)

1,071 阅读5分钟

大家好,因为个人水平有限,肯定会有不准确的地方,希望多多指教!

q1:移动端适配是啥?响应式布局又是啥?

移动端适配是指一套代码在不同的移动设备上能够自适应的显示,主要解决的是不同的手机上看到的页面不一致的问题;

那么移动设备有什么不同呢?dpr(设备像素比)

所以实际上要做的就是根据不同的dpr来对页面进行不同的缩放。

响应式布局则是根据利用媒体查询来查询,在pc,平板,手机上显示不同的样式。

响应式长这样:

@media (max-width: @screen-xs-max) { ... }
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) { ... }
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) { ... }
@media (min-width: @screen-lg-min) { ... }

因为媒体查询查询的宽度是可见区域的宽度,而移动端适配会会缩放视口宽度,所以二者不能同时使用。

q2:视窗,物理像素,设备独立像素,设备像素比的介绍?

视口

可见视口:就是移动设备上可以被我们看见的部分。宽度在移动端通过window.innerWidth获得(仅限移动端,PC上哪怕是chrome模拟也会有不同的结果)。

布局视口:动浏览器就决定默认情况下把viewport设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。

理想视口:理想视口,其实就是设备的可见区域,和可见视口一致。

设置Ideal Viewport的好处是,只要按照Ideal Viewport来设计样式稿,用户就不用能最完美的查看网站的内容——既不用左右滑动,也不用放大缩小。

设置理想视口:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
物理像素

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。

设备独立像素

设备独立像素:又称为CSS像素,就是我们日常代码中使用的像素。浏览器内的一切长度都是以CSS像素为单位的,CSS像素的单位是px。

设备像素比

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系。

可以通过 window.devicePixelRatio 获取到当前设备的dpr。

比如说对于iOS的retina屏,一个设备独立像素就对应着4个物理像素。这样的设计可以使画面更加清晰锐利,如下图:

q3:rem布局的原理?flexible.js干了啥?post--plugin-css干了啥?

rem:相对于根元素 <html>font-size 的比值。

例如div宽度为37.5px, 根元素html的font-size为75px,那么div的宽度也可以换算为0.5rem。

正是因为这个特性,有个聪明人就想到了:

假如我页面里的单位都用rem作为单位,然后根据不同的dpr来设置html的font-size岂不是就解决了这个问题?

那么问题来了:

  1. 平时我都用px作为单位来写css,怎么让我页面里的单位全部换成rem单位?
  2. 然后根据不同的dpr来设置html的font-size,这个js过程做好封装起来,以后供大家使用?

于是

post--plugin-css就解决了第一个问题,将px换算为rem(sass也可以做到该功能);

flexible.js就解决了第二个问题,根据不同dpr的设备来计算font-size;

  1. ​ 发现html多了一个data-dpr的属性,以及设置了font-size
  2. ​ meta的content不能设置”width=device-width“

于是实际中页面渲染就是这样一个过程:

这个是iphone6,dpr是2,我就把页面缩小到0.5倍。

这个是iponeX,dpr是3,我就把页面缩小到0.3倍。

所以移动端的ui设计图通常是750px,因为ipone6是375px,这样就可以适应大部分手机了。

q4:rem布局需要解决的问题?文本,1px边框,背景图?

文本

为了避免文本出现13px或者15px这种情况,所以通常需要自行设置。

div {
    width: 1rem; 
    height: 0.4rem;
    font-size: 12px; // 默认写上dpr为1的fontSize }
[data-dpr="2"] div {
    font-size: 24px;
}
[data-dpr="3"] div {
    font-size: 36px;
}

也可以利用sass方法一劳永逸解决这个问题。

1px边框

因为缩放的问题,设置的1px边框会变粗,达不到ui想要的1px(物理像素)的效果。

常见解决方法有:

  1. 根据dpr设置边框宽度为1px或0.5px;
  2. 让ui制作一个1px宽高的图片,然后利用border-image或者background-image来实现。
  3. 利用伪类,将伪类的高度设置为1px,再利用transform属性缩放高度。
背景图

backgroun-size: cover/contain;

让背景图自适应显示。

q5:postcss-plugin-px2rem+lib/flexible在vue-cli中的工程实践?

首先安装postcss-plugin-px2rem

npm install postcss-plugin-px2rem --save

在vue.config.js中配置postcss-plugin-px2rem的主要字段

rootValue: 37.5, 换算基数,1rem相当于10px,值为37.5时,1rem为20px,淘宝的flex默认为1rem为10px
unitPrecision: 5,允许REM单位增长到的十进制数字。
propWhiteList: [],默认值是一个空数组,这意味着禁用白名单并启用所有属性。
propBlackList: [],黑名单*
exclude: /(node_module)/,默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)\/如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
selectorBlackList: [],要忽略并保留为px的选择器
ignoreIdentifier: false,(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为truereplace: true,(布尔值)替换包含REM的规则,而不是添加回退。
mediaQuery: false, 布尔值)允许在媒体查询中转换px。
minPixelValue: 3,设置要替换的最小像素值(3px会被转rem)。 默认0

然后安装lib/flexible

npm install lib/flexible --save

最后在main.js中引入

import "lib-flexible"

运行发现已生效

相关链接

  1. 使用Flexible实现手淘H5页面的终端适配 - Arlar - 博客园 (cnblogs.com)
  2. 基于淘宝弹性布局方案lib-flexible的问题研究 - 流云诸葛 - 博客园 (cnblogs.com)
  3. (35) 茴字的四种写法—移动适配方案的进化_汤姆C - SegmentFault 思否