一、 rem+flexible+postcss-pxtorem
- amfe-flexible 是配置可伸缩布局方案,主要是将 1rem 设为 viewWidth/10
- postcss-pxtorem是postcss的插件,用于将像素单元生成rem单位。
安装 amfe-flexible和ostcss-pxtorem
npm i amfe-flexible postcss-pxtorem --save-dev
配置
vue.config.js文件
module.exports = { //...其他配置 css: { loaderOptions: { postcss: { plugins: [ require('postcss-pxtorem')({ rootValue: 37.5, propList: ['*'] }) ] } } }, }
或在根目录新建一个名为postcss.config.js的文件
module.exports = { plugins: { 'postcss-pxtorem': { rootValue: 37.5, propList: ['*', '!border'] } } }
代码设配
import 'amfe-flexible/index.js' const baseSize = 100 // 这个是设计稿中1rem的大小。 function setRem () { // 实际设备页面宽度和设计稿的比值 const scale = (document.documentElement.clientWidth || document.body.clientWidth) / 750 // 计算实际的rem值并赋予给html的font-size document.documentElement.style.fontSize = (baseSize * scale) + 'px' } setRem() window.addEventListener('resize', () => { setRem() })
注意点:
1.rootValue根据设计稿宽度除以10进行设置,这边假设设计稿为375,即rootValue设为37.5;
2.propList是设置需要转换的属性。*为所有都进行转换
二、rem+viewport+postcss-pxtorem
设置 viewport
<!-- rem-demo/public/index.html --> <meta name="viewport" content="width=device-width,initial-scale=1">
动态设置 rem 的值:
// rem-demo/util/rem.js // 设置基准大小 const baseSize = 32 function setRem () { // 当前页面宽度相对于 750 宽的缩放比例 const scale = document.documentElement.clientWidth / 750 document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px' } // 初始化 setRem() window.onresize = function () { setRem() }
安装postcss-pxtorem
npm i postcss-pxtorem --save-dev
配置
// rem-demo/vue.config.js module.exports = { lintOnSave: true, css: { loaderOptions: { postcss: { plugins: [ require('postcss-pxtorem')({ rootValue : 16, //(数字,函数) 根元素字体大小 unitPrecision: 5, //(数字)允许REM单位增长的十进制数字 replace: true, // (布尔值)替换包含rems的规则,而不添加后备 mediaQuery: false, // (布尔值)允许在媒体查询中转换px minPixelValue: 0, // (数字)设置要替换的最小像素值 selectorBlackList : [], // 忽略转换正则匹配项 propList : ['*'], // 可以从px转换为rem的属性,匹配正则 exclude: /node_modules/i // (字符串,正则表达式,函数)要忽略并保留为px的文件路径 }), ] } } } }
总结:
优点:rem 布局能很好的实现在不同尺寸的屏幕横向填满屏幕,且在不同屏幕元素大小比例一致
缺点:在大屏设备(Pad)上,元素尺寸会很大,页面显示更少的内容。
针对大屏改进方案:
- 限制 rem 的最大值,
- 通过媒体查询,限制内容最大宽度
三、vw+viewport+postcss-pxtorem
设置viewport
<!-- rem-demo/public/index.html --> <meta name="viewport" content="width=device-width,initial-scale=1">
安装postcss-pxtorem
npm i postcss-pxtorem --save-dev
创建postcssrc.js
module.exports = { plugins: { autoprefixer: {}, // 用来给不同的浏览器自动添加相应前缀,如-webkit-,-moz-等等 'postcss-px-to-viewport': { unitToConvert: 'px', // 要转化的单位 viewportWidth: 750, // UI设计稿的宽度 unitPrecision: 6, // 转换后的精度,即小数点位数 propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw selectorBlackList: ['wrap'], // 指定不转换为视窗单位的类名, minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换 mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false replace: true, // 是否转换后直接更换属性值 exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配 landscape: false, // 是否处理横屏情况 }, }, };
总结
优点:
vw、vh布局能良好的实现在不同尺寸的屏幕横向填满屏幕,使用 postcss-px-to-viewport
能很好的帮我们进行单位转换
缺点:
- 无法修改 vw/vh 的值,在大屏设备(Pad)中元素会放大,且无法通过 js 干预
- 兼容性- 大多数浏览器都支持、ie11不支持 少数低版本手机系统 ios8、android4.4以下不支持