基于REM的移动端自适应布局方案

9,126

背景

现在工作中有超过一半的时间用于移动端项目的开发,包括app嵌入页,微信页面和移动wap页。

开发移动端页面跟开发PC页面的一个大区别就是移动端对响应式布局的要求更高,不能像PC页面一样设计几个断点利用媒体查询,两边留空白就解决。移动端页面需要把屏幕空间都利用上,而移动设备的尺寸和分辨率多种多样,解决移动端页面的自适应布局问题是搭建新的移动端项目的重点和难点。

经过研究,我在公司的多个移动端项目使用了REM布局来解决移动端自适应布局的问题。

REM介绍

rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位,rem布局是一个流行的解决移动端响应式布局的方案。在页面初始化时,使用JS根据屏幕的尺寸和dpr等信息设置rem的大小,而在css中写下元素的高度等信息时,使用rem。如将rem设置为100px,则元素的高度为36px时,需要将元素的高度写成0.36rem。

传统的REM布局遇到的问题

以100像素为例,很多常见的属性如字体大小需要写成0.12rem等,可读性较差,输入起来也不方便,降低了工作效率。

解决方案

在webpack中使用px2rem-loader。用法如下


rules: [
  {
    test: /\.css$/,
    use: ['style-loader', 'css-loader', 'px2rem-loader?remUnit=75&remPrecision=8']
  }
]

这样便可以应对常见的750px的设计图,直接按照设计图的尺寸来填写属性大小就好,
注意,还需要在html文件中引入flexible文件


<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.2/??flexible_css.js,flexible.js"></script>

踩到的坑

微信浏览器如果退回的话,页面被缓存,但是js文件没有重新调用,会导致布局混乱。需要调用pageshow事件来解决

e.addeventListener('pageshow', function(e) {
	// d的作用是重新设置documentElement的fontsize为clientWidth的1/10
	e.persisted&&d()
})

深入

你也许会对flexible.js做了什么比较感兴趣。在这之前,需要简单了解一下viewport的知识

viewport
viewport meta标签

viewport meta标签有六个属性

  1. width:设置layout viewport 的宽度,为一个正整数,或字符串”width-device”
  2. initial-scale:设置页面的初始缩放值,为数字,可带小数
  3. minimum-scale: 允许用户的最小缩放值,为数字,可带小数
  4. maximum-scale:允许用户的最大缩放值,为数字,可带小数
  5. height 设置layout viewport 的高度
  6. user-scalable 是否允许用户进行缩放,值为”no”或”yes”
三种viewport
  1. layout viewport 布局视窗

网站的宽度,可以通过document.documentElement.clientWidth获取,通过viewport meta标签设置

  1. visual viewport——视觉视窗

代表浏览器可视区域的大小,可以通过 document.documentElement.innerWidth来获取

  1. ideal viewport——理想视窗

跟移动设备相关的viewport,移动设备的宽度。ihpone的值是320

他们之间的关系

visual viewport width = ideal viewport width / zoom factor

zoom factor可以设置initial-scale来控制
当visual viewport = layout viewport时,页面无水平滚动条,刚好显示全部内容

如果不设置initial-scale,通过设置viewport meta的width为device-width,可以令layout viewport等于ideal viewport,从而达到页面无水平滚动条的效果

lib-flexible原理
  1. 获取dpr和设置dpr的倒数scale
  2. 动态生成viewport meta,initial-scale值为scale
  3. 设置rem为clientWidth(layoutview port width) 的1 / 10

这时我们我们开发项目只要注意屏幕的宽度是10rem就可以了

最后

其实REM方案主要还是以clientWidth的1/10为基本单位设置元素的尺寸来达到自适应的目的。可以使用VW来代替,也有px2vw之类的插件。

要达到自适应布局,还可以使用百分比、flex布局或是grid布局,这里就不细说了。

本文章为前端进阶系列的一部分,
欢迎关注和star本博客或是关注我的github

参考

  1. px2rem
  2. 移动前端开发之viewport的深入理解