flexible.js分析及移动端REM适配插件

1,324 阅读4分钟

(function flexible (window, document) {

// 获取html的根元素

var docEl = document.documentElement

// dpr 物理像素比

var dpr = window.devicePixelRatio || 1

// adjust body font size 设置body 的字体大小

function setBodyFontSize () {

// 如果页面中有body 这个元素 就设置body的字体大小

if (document.body) {

document.body.style.fontSize = (12 * dpr) + 'px'

}

else {

// 如果页面中没有这个元素 则等着 页面主要的DOM元素加载完毕再去设置body 的字体大小

document.addEventListener('DOMContentLoaded', setBodyFontSize)

}

}

setBodyFontSize();

// set 1rem = viewWidth / 10 设置html元素文字的大小

function setRemUnit () {

var rem = docEl.clientWidth / 10

docEl.style.fontSize = rem + 'px'

}

setRemUnit()

// reset rem unit on page resize 当页面尺寸发生变化时,再次调用 要重新设置rem 大小,

window.addEventListener('resize', setRemUnit)

// pageshow 是我们重新加载页面触发的事件

window.addEventListener('pageshow', function (e) {

//e.persisted返回的是true 如果这个页面是从缓存取过来的页面 也需要重新计算一下rem的大小

if (e.persisted) {

setRemUnit()

}

})

// detect 0.5px supports 有些浏览器不支持0.5像素的写法

if (dpr >= 2) {

var fakeBody = document.createElement('body')

var testElement = document.createElement('div')

testElement.style.border = '.5px solid transparent'

fakeBody.appendChild(testElement)

docEl.appendChild(fakeBody)

if (testElement.offsetHeight === 1) {

docEl.classList.add('hairlines')

}

docEl.removeChild(fakeBody)

}

}(window, document))

flexible与rem适配问题

1. flexible: 将当前屏幕进行十等分,将一份的值,赋值给html的font-size : 比如当前屏幕是375 ,那么font-size就是37.5px (根据实际屏幕大小设置基准值/1rem大小) 

2. pxtorem: 配置rootValue: 75/37.5 rootValue应该设置为当前设计稿的十分之一,例如设计稿是 750 宽,则应该设置为 75 (根据设计稿设置基准值/1rem大小) 就是1rem的大小: 1rem = 75px; 实际应用: 如果现在div:宽度经过测量 发现是 375px (750设计稿中) div{ width:375px; } 代码运行起来,pxtorem 插件会将 px尺寸转换为rem : 375/75 = 5rem 比如现在的屏幕大小是 : 1024px ---- 现在的font-size = 102.4px , 真实的div大小是多少:512px 比如现在的屏幕大小是 : 750px ---- 现在的font-size = 75px , 真实的div大小是多少:375px 比如现在的屏幕大小是 : 414px ---- 现在的font-size = 41.4px , 真实的div大小是多少:207px 公式: 设计稿中标签的大小 / rootValue * html的font-size

移动端 REM 适配

Vant 中的样式默认使用 px 作为单位,如果需要使用 rem 单位,推荐使用以下两个工具:

下面我们分别将这两个工具配置到项目中完成 REM 适配。

一、使用 lib-flexible 动态设置 REM 基准值(html 标签的字体大小)

1. 安装    yarn add amfe-flexible

2. 在main.js中加载执行该模块      import 'amfe-flexible'

最后测试:在浏览器中切换不同的手机设备尺寸,观察 html 标签 font-size 的变化。

二、使用 postcss-pxtorempx 转为 rem

1. 安装 npm install postcss-pxtorem -D   ||   yarn add -D postcss-pxtorem

2. 然后在项目根目录中创建 .postcssrc.js 文件 (这个配置文件详解)

module.exports = {

plugins: {

// VueCli 内部配置了 autoprefixer插件的配置    作用:生成浏览器CSS样式规则前缀

'autoprefixer': {

// 配置要兼容的环境信息

// browsers: ['Android >= 4.0', 'iOS >= 8']

},

// 配置使用postcss-pxyorem 插件

 // 作用:把 px 转为 rem

'postcss-pxtorem': {

// 能够把所有元素的px单位转成Rem

// rootValue: 转换px的基准值。

// 例如一个元素宽是75px,则换成rem之后就是2rem。

// rootValue: 37.5,

// 如果是vant样式使用37.5 换算

// 如果是自己的样式使用75 换算

// rootValue 支持两种类型

// 数字 :固定的数组

// 函数 :可以动态处理返回

// postcss-pxtorem 处理每个css文件的时候都会调用这个函数

// 它会把被处理的css文件相关的信息通过参数传递给该函数

// file :vant-button.css file:login.vue

rootValue({file}){

// 返回索引,没有返回-1

// return file.indexOf("vant") !== -1? 37.5 : 75

// 返回布尔值

return file.includes("vant")? 37.5 : 75

},

propList: ['*']

}

}

}

3、配置完毕,重新启动服务

最后测试:刷新浏览器页面,审查元素的样式查看是否已将 px 转换为 rem

需要注意的是:该插件不能转换行内样式中的 px,例如 <div style="width: 200px;"></div>

实现:使用 vw 完成移动端适配

  • 有一个控制台警告可忽略,或者使用 postcss-px-to-viewport-8-plugin 代替当前插件

安装:

npm install postcss-px-to-viewport -D  
yarn add -D postcss-px-to-viewport
pnpm add -D postcss-px-to-viewport 

配置: postcss.config.js

// eslint-disable-next-line no-undef
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      // 设备宽度375计算vw的值
      viewportWidth: 375,
    },
  },
};