(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-pxtorem 将 px 转为 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,
},
},
};