以vue项目为例,先创建一个rem.js文件,然后写如下代码:
然后在vue项目中main.js入口文件 中引入rem.js就可以了
rem函数写法一:
// 设计稿自定义为750px 利用测量的px大小除以50px 即可得到所需rem值
(function () {
remLayout();
function remLayout() {
// 获取屏幕宽度
var w = document.documentElement.clientWidth;
w = w > 768 ? 768 : w;
w = w <= 320 ? 320 : w;
// document.documentElement 获取到的html标签
document.documentElement.style.fontSize = w / 7.5 + 'px';
}
// resize 监听页面变化
window.addEventListener('resize', function () {
remLayout();
}, false);
})();
如果项目中引入第三方组件,还要清楚第三方组件的默认像素大小
下载 postcss-pxtorem 插件
cnpm install postcss-pxtorem -S
根目录新建postcss.config.js
module.exports = {
plugins: {
'autoprefixer': {
browsers: ['Android >= 4.0', 'iOS >= 7']
},
// vant 37.5 [link](https://github.com/youzan/vant/issues/1181)
'postcss-pxtorem': {
rootValue: 75,
propList: ['*'],
selectorBlackList: ['van-']
}
}
}
注意 selectorBlackList: [‘van-’] 这里是为了过滤掉 vant库的CSS, vant的CSS 单位用的是PX,不过滤的话,用这个UI库会变小
rem函数第二种写法:
// 设置 rem 函数
function setRem () {
// 320 默认大小16px; 320px = 20rem ;每个元素px基础上/16
let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
//得到html的Dom元素
let htmlDom = document.getElementsByTagName('html')[0];
//设置根元素字体大小
htmlDom.style.fontSize= htmlWidth/10 + 'px';
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.onresize = function () {
setRem()
}
注意 这里 htmlWidth/10 的 10 和 rootValue 的值的乘 应该为设计图的总宽度
也就是如果设计图的总宽度是750的话 75 * 10 = 750
需要理解的一个知识点:
物理像素:是手机的实际像素。
设备屏幕实际拥有的像素点。比如iPhone 6的屏幕在宽度方向有750个像素点,高度方向有1334个像素点,所以iPhone 6 总共有750*1334个物理像素。
逻辑像素:即css里常用的px。
也叫“设备独立像素”(Device Independent Pixel, DIP),可以理解为反映在CSS/JS代码里的像素点数。
设备像素比(Device Pixel Ratio, DPR):一个设备的物理像素与逻辑像素之比。
在iphone6里物理像素是750px 1334px,即水平750px,竖直1334个像素点,而前端移动端通常以这个标准给设计稿,那么2倍稿是什么意思呢?iphone6的css逻辑像素是350px 667px。也就是说一个你在css里写1px,那么在真机里,它会用它的2个逻辑像素来填充。
window.devicePixelRatio 可以获取设备比;
一边框像素问题:
1px边框问题
在苹果的带动下,Retina技术在移动设备上已经成了标配,所以前端攻城狮必须直面如下事实:
你想画个1px的下边框,但屏幕硬是塞给你一条宽度为2—3个物理像素的线。
你没法像安卓或iOS的同事那样直接操纵物理像素点。
这就是初级前端面试必考题之“1px边框问题”的由来。
1px边框问题的解法千奇百怪,各显神通,但以我的实践经验,最推崇的方法还是利用CSS3的transform: scale,因为简单直接、适用性和兼容性好。
你不是给我两个物理像素点吗?加个transform: scale(0.5),只剩一个点了~
三个物理像素点?那就scale(0.33)!
使用CSS的-webkit-min-device-pixel-ratio媒体查询可以针对不同的DPR做出处理 ,下面以Less代码为例:
@media (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){
.border-bt-1px(@color) {
position: relative;
&::after {
position: absolute;
bottom: 0;
width: 100%;
height: 1px;
background-color: @color;
transform: scaleY(0.5);
}
}
}
上面介绍的是只有一边的情景,如果是四面都要有框,咋办?
那就画个DPR倍大小的矩形框,再scale一下,完事~