If I change the width
, height
and transform
properties simultaneously it produces pretty weird transition. The example is below. Look at the rectangle and its position relative to the red line.
I know replacing transform
property by left
and top
properties fix it, but it's not the solution in my case because it produces performance and other issues.
UPDATE: the scale
transform is not solution, because in the real case proportions can be changed and the internal content should not be affected by scale transformation. –
const states = [{
height: '250px',
width: '500px',
transform: 'translate(50px, 50px)'
},
{
height: '150px',
width: '250px',
transform: 'translate(175px, 100px)'
},
]
let currentState = 0;
function updateState() {
const box = document.querySelector(".box");
const state = states[currentState];
currentState = (currentState + 1) % states.length
box.style.height = state.height
box.style.width = state.width
box.style.transform = state.transform
}
.button {
position: absolute;
top: 0;
left: 0;
}
.box {
transition: 0.4s ease-in-out;
position: absolute;
background: #AAA;
left: 0;
top: 0;
}
.line {
position: absolute;
left: 300px;
height: 100%;
background: red;
width: 1px;
}
.small-box {
width: 10px;
height: 10px;
border: solid 1px black;
position: absolute;
transform: translateX(-50%);
}
<div class="box">
<div class="small-box" style="left: 50%; top:0"></div>
</div>
<div class="line"></div>
<button class="button" onclick="updateState()">Update State</button>
I change transform
property on js : 50px
and 100px
is become calc(300px - 50%)
calc(300px - 50%)
is line position minus half of .box
's div
const states = [{
height: '250px',
width: '500px',
transform: 'translate(calc(300px - 50%), 50px)'
},
{
height: '150px',
width: '250px',
transform: 'translate(calc(300px - 50%), 100px)'
},
]
let currentState = 0;
function updateState() {
const box = document.querySelector(".box");
const state = states[currentState];
currentState = (currentState + 1) % states.length
box.style.height = state.height
box.style.width = state.width
box.style.transform = state.transform
}
.button {
position: absolute;
top: 0;
left: 0;
}
.box {
transition: 0.4s ease-in-out;
position: absolute;
background: #AAA;
left: 0;
top: 0;
}
.line {
position: absolute;
left: 300px;
height: 100%;
background: red;
width: 1px;
}
.small-box {
width: 10px;
height: 10px;
border: solid 1px black;
position: absolute;
transform: translateX(-50%);
}
<div class="box">
<div class="small-box" style="left: 50%; top:0"></div>
</div>
<div class="line"></div>
<button class="button" onclick="updateState()">Update State</button>