摘要:电脑屏幕多种,再加上系统自己的缩放设置,使得屏幕分辨率不一,于是我们使用px单位也就会遇到大小不一的麻烦,虽说有百分比,em,rem,vh,vw等各种css单位,但是它们对动画不友好,也不够直接,于是我实现一下通用的js自适应px单位。直接一个函数搞定,方便省事,效果一致。
主要原理就是利用css属性transform,缩放body以完整适应视口。原先相对视口的单位vh,vw都会变得不正常,不能使用;相对html的font-size的px值的rem,em等可以正常使用的,相对父元素的百分比也可以使用。
需要注意的是,假如targetWidth与你的屏幕分辨率或视口大小不一致,那浏览器在鼠标hover时实时显示的盒大小是缩放后计算的,控制台的盒模型的数据不是经过缩放的,所以只能参考控制台的(小问题)。
一个问题是元素的getBoundingClientRect()返回的值是缩放后的,需要使用元素的offset值或通过scale还原计算,还有鼠标点击事件,只有offset开头的单位是没缩放的。其他正常。这可能对一些库不友好。
效果
代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script>
(function(targetWidth = 1920) {
let style = document.createElement('style');
style.innerHTML = `
html {
width:${targetWidth + 'px'};
transform-origin: top left;
overflow: hidden;
}
body {
width: 100%;
height: 100%;
margin: 0;
overflow: auto;
}
`;
document.head.appendChild(style);
let myStyle = document.createElement('style');
document.head.appendChild(myStyle);
let adjustWindow = () => {
let scale = window.innerWidth / targetWidth;
let height =
(window.innerHeight * targetWidth) / window.innerWidth + 'px';
myStyle.innerHTML = `html{height:${height};transform:scale(${scale});}`;
};
adjustWindow();
window.addEventListener('resize', () => {
adjustWindow();
});
})();
</script>
</head>
<body style="background: salmon">
<div style="font-size: 30px;width:100%">
嗯嗯eeeeeeeeeeeeeeeeeeee
</div>
<div style="width:100vw;height:20px;background: skyblue;">100vw</div>
<br />
<br />
<br />
<div style="width:100%;height:20px;background: skyblue;">100%</div>
<div
style="width: 20px;height: 100vh;position:absolute;left:50%;top:0;background: slategrey;"
>
100vh
</div>
<div
style="width: 20px;height: 100%;position:absolute;left:60%;top:0;background: slategrey;"
>
100%
</div>
<div
style="width: 100px;height:100px;background: red;position: absolute;left:0;top:50%;"
></div>
<div
style="width: 100px;height:100px;background: blue;position: absolute;right:0;top:0;"
></div>
<div
style="width: 100px;height:100px;background: green;position: absolute;left:0;bottom:0;"
></div>
</body>
</html>