对于一个div有如下css
width:100px;
height:100px;
transform:scale(0.7);
由于scale不改变盒子大小,所以这个div占据的盒子大小还是100px,页面布局不会发生变化,如下图中左边那个。
而有一些时候我们希望他缩小之后盒子大小也跟着缩小,如下图中右边那个。
接下来我们将解决这个问题。源码有原生js与vue两种版本
解决思路
<!-- html结构 -->
<div id="showBox">
<div id="contBox" style="background: green;">text</div>
</div>
- 通过getBoundingClientRect获取contBox的宽高
- 为contBox设置scale,同时设置变换中心为左上角transform-origin: left top;
- 计算并设置showBox的变换后的宽高:contBox.width*scale。
原生js源码
<html>
<head>
<title>解决transform:scale(n)占位依旧是100%的问题</title>
<meta charset="UTF-8"/>
<style type="text/css">
#contBox{
width: 100px;
height: 100px;
transform-origin: left top;
}
</style>
</head>
<body>
<div id="showBox">
<div id="contBox" style="background: green;">text</div>
</div>
<div>证明效果成功使用,请删掉</div>
<script type="text/javascript">
function setScale(scale){
var contBox=document.getElementById("contBox");
var showBox=document.getElementById("showBox");
var boundClient=contBox.getBoundingClientRect();
contBox.style.transform="scale("+scale+")";
showBox.style.width=boundClient.width*scale;
showBox.style.height=boundClient.height*scale;
}
setScale(0.4); //设置为原来的0.4倍大小
</script>
</body>
</html>
vue源码
//组件源码:set-scale.vue
<template>
<div class="showBox" ref="showBox" :style="{width:width+'px',height:height+'px'}">
<div class="contBox" ref="contentBox" :style="{transform:transform}">
<slot></slot>
</div>
</div>
</template>
<script>
export default{
props:["scale"], //接收一个参数为缩放倍数
data(){
return {
width:1,
height:1,
transform:"scale(1)"
}
},
mounted() {
const boundClient=this.$refs.contBox.getBoundingClientRect();
this.transform=`scale(${this.scale})`;
this.width=boundClient.width*this.scale;
this.height=boundClient.height*this.scale;
},
}
</script>
<style scoped="scoped">
.contBox{
transform-origin: left top;
}
</style>
//使用方法:App.vue
<template>
<set-scale scale="0.4">
<div>这里面是需要缩放的内容,当然也可以import外部的组件</div>
</set-scale>
</template>
<script>
import setScale from "./set-scale.vue";
export default{
components:{
setScale
}
}
</script>