摘要:電腦屏幕多種,再加上系統自己的縮放設置,使得屏幕分辨率不一,於是我們使用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>