阅读 894

移动端适配方案实践-rem和vw

移动端适配方案

1.rem实现移动端适配

2.vw实现移动端适配

3.百分比适配

4.@media适配

1.rem实现移动端适配

我们常用的响应式布局方案是--利用rem单位,通过计算不同移动端下HTML根字体大小,来实现页面的适配。

原理讲解

首先让我们来了解一下什么是rem?rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。它的相对是相对于HTML根元素来说的,假如我们设置HTML根节点的字体大小fontSize为10px,那么在这个HTML里面所有设置rem单位的DOM元素的像素值为y(px)=x(rem) * 10。例如:

 body {
   fontSize: 10px
 }
 p {
   width: 10rem
 }
 则p标签的宽度为y(px) = 10(rem) * 10(body fontSize) = 100(px)
复制代码

了解了rem单位以后,rem实现移动端适配的原理就变得很简单了--对不同尺寸的设备设置不同的根字体大小,利用rem尺寸,就可以在不同的设备上展实现移动端适配,重点在于计算根字体的大小。 下面我们来说一下,不同设备中怎么计算根字体的大小

第一步,假设视觉稿为1080px,可以根据视觉稿调整。
第二步,获取设备的视口宽度document.documentElement.clientWidth(不同的设备布局视口不一样),假设某款手机的视口宽度为320px
第三步,先从ui设计稿的角度来看,取100px(主流做法)为html根元素的fontSize的,则10.8rem对应了1080px(视觉稿)的整个宽度
第四步,现在我们的手机实际宽度为320px,则实际上html根元素的fontSize的大小: y(px)/100(px) = 320px/1080px    y = 29.6px,这样我们就计算出了fontSize的大小
第五步,将px尺寸转换为rem尺寸
复制代码

实践

第一步,新建page-scale.js,计算并设置html根元素的fontSize的大小,并监听resize事件更新fontSize的大小

const uiWidth = 1080;
//设置html默认字体为100px body字体为16px
document.body.style.fontSize = "16px";
    
//监听浏览器缩放事件
window.addEventListener("resize", resizeHandler);

//计算html字体大小
resizeHandler() {
   let contW = Math.floor(document.documentElement.clientWidth);
   let fontS = (contW / uiWidth) * 100;
   document.documentElement.style.fontSize = fontS + "px";
}
复制代码

第二步,利用postcss-pxtorem插件,将所有px尺寸转换为rem尺寸

module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 100,//根元素字体大小或根据输入参数返回根元素字体大小,此时,ui稿的1080px(全部宽度),会被转换为10.8rem,其他尺寸y(rem) = 10.8(rem) * x(px) / 1080(px)
      propList: [],// 需要做转换的属性
      selectorBlackList:[], // 忽略的选择器
    }
  }
}
复制代码

通过page-scale.js文件的引入和webpack打包引入postcss-pxtorem单位转换软件,就可以利用rem实现移动端适配了,但是使用rem单位实现移动端适配有一个缺点--它需要内嵌一段js脚本去动态计算根元素的大小,下面我们来看一下vw是怎么实现移动端适配的。

2.vw实现移动端适配

原理讲解

接下来,讲一下怎么使用vw单位实现页面布局。

首先让我们来了解一下什么是vw?

vw是视口单位,视口单位中的“视口”,在桌面端指的是浏览器的可视区域;在移动端指的就是Viewport中的Layout Viewport(布局适口)。

现在我们来看一下vw与视口单位的转换关系

单位解释
vw1vw = 视口宽度的1%
vh1vh = 视口高度的1%
vmin选取vw和vh中最小的那个
vmax选取vw和vh中最大的那个

知道vw单位以后,不难猜到怎么利用它做移动端适配--针对不同的机型,我们只要算出ui设计稿尺寸(一般为1080px)与视口尺寸(假设为375px)的比例关系,然后用vw尺寸去代替px尺寸就好了

k = 1vw = 1080px / 375px = 2.88

y(vw) = 设计稿的尺寸x(px)/ k 
复制代码

通过以上公式就可以得出每个dom元素的vw尺寸,然后进行设置就可以了。

但是在实际开发过程当中,计算每一个dom元素的vw尺寸又是很繁琐的,不要担心,我们可以利用(postcss-px-to-viewport)插件来帮我们完成这项计算工作

postcss-px-to-viewport插件是postCSS工具下的插件,它的作用是把css中包含的所有px尺寸转换为vw尺寸。在介绍postcss-px-to-viewport插件的用法之前,我们来简单了解一下PostCSS工具。

PostCSS是使用js插件转换css的工具,你可以把它可以理解成为一个平台,里包含了许多对css进行处理的插件。它本身只是负责把css代码解析成抽象语法树结构(Abstract Syntax Tree,AST),我理解就是使用js对象树来描述css,然后就可以通过修改js对象的方式来修改css,达到对css优化和调整的目的。可以参考下图理解一下PostCss的作用。

postcss-px-to-viewport就是PostCSS工具下的插件,原理图如下: postcss-px-to-viewport插件的用法很简单,PostCSS支持webpack打包,直接在webpack下引用并对插件进行配置即可。

下面介绍简单介绍一下操作步骤:

实践

首先第一步,安装插件

npm install postcss-px-to-viewport
复制代码

第二步,在webpack中引入插件,并对插件进行一些配置,具体代码如下(vue.config.js):

const PxtoVw = require('postcss-px-to-viewport')
    
module.exports = {
  css: {
     loaderOptions: {
        postcss: {
       	    plugins: [
               new PxtoVw({
                  unitToConvert: 'px', // 需要转换的单位,默认为"px";
                  viewportWidth: 1080, // 设计稿的视口宽度,进行比例换算
                  unitPrecision: 2, // 单位转换后保留的小数位数
                  propList: ['*'], // 要进行转换的属性列表,*表示匹配所有,!表示不转换
                  viewportUnit: 'vw', // 转换后的视口单位
                  fontViewportUnit: 'vw', // 转换后字体使用的视口单位
                  selectorBlackList: [], // 不进行转换的css选择器,继续使用原有单位
                  minPixelValue: 1, // 设置最小的转换数值
                  mediaQuery: false, // 设置媒体查询里的单位是否需要转换单位
                  replace: true // 是否直接更换属性值,而不添加备用属性
                  exclude: [/node_modules/] // 忽略某些文件夹下的文件  由于引用了game/vui的toast组件,需要对其进行vm转换适配
              })
            ]
         }
      }
   }
}
 
复制代码

插件配置好以后,webpack打包项目时就会把css中的px尺寸按照约定好的比例关系转换为vw尺寸,实现移动端适配,vw和rem是目前主流的移动端适配方案,兼容性不错。

3.百分比适配

原理简介

利用%单位来实现移动端适配,每个元素的大小都相对于父元素的大小利用百分比的单位来实现,使用来定义子元素的宽度。

属性参考对象
height/width相对于有定位属性的父元素
top/bottom/left/right相对于子元素的直接父元素
padding/margin相对于直接父元素
border-radius相对于自身

这种方案存在致命性问题,不能调整字体的大小,所以已经被淘汰了,基本不怎么使用。

4.@media适配

原理简介

@media是css3的新属性,它的原理是监控移动端设备的宽度,然后根据不同的宽度,适配不同的css样式,来实现移动端适配

@media screen and(max-width:300px){
	html{
	 font-size:32px;
	}
}

@media screen and(max-width:600px){
	html{
	 font-size:32px;
	}
}

@media screen and(max-width:900px){
	html{
	 font-size:32px;
	}
}
复制代码

优点:避免rem和vw出现的精度问题

缺点:代码量大,维护不方便

文章分类
前端
文章标签