I would like to be able to shrink an HTML tag to make it disappear, and have a smooth disappearance for the remaining items (so that they don't jump where the tag used to be)
const div = document.querySelector('.toGo');
div.addEventListener('click', event => {
div.className += ' animate';
// Simulate Angular's DOM modification
setTimeout(() => div.style.display = 'none', 1100);
setTimeout(() => div.style.display = 'block', 1200);
setTimeout(() => div.className = 'toGo', 1300);
});
.toGo, .toStay {
height: 50px;
width: 100%;
background: coral;
transition: all 1000ms ease-in-out;
overflow: hidden;
}
.toStay {
margin: 12px 0;
}
.animate {
height: 0;
width: 0;
opacity: 0;
}
<div class="toGo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>
<p>Click on the first div</p>
Right now, as you can see, the text is shifting because the space is shrinking.
At first, I tried with the transform
property, but the second div was jumping at the place of the first one (because I am using Angular and the framework removes the first div from the DOM once the animation is complete).
const div = document.querySelector('.toGo');
div.addEventListener('click', event => {
div.className += ' animate';
// Simulate Angular's DOM modification
setTimeout(() => div.style.display = 'none', 1100);
setTimeout(() => div.style.display = 'block', 2100);
setTimeout(() => div.className = 'toGo', 2200);
});
.toGo, .toStay {
height: 50px;
width: 100%;
background: coral;
transition: all 1000ms ease-in-out;
overflow: hidden;
}
.toStay {
margin: 12px 0;
}
.animate {
transform: scale(0);
opacity: 0;
}
<div class="toGo">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>
<p>Click on the first div</p>
I then tried this solution with the width/height, but the text is shifting. I then finally tried with a container in it, but it didn't change a thing (unless I set a fixed size to that inner container).
Is there a way to achieve that, without setting fixed width/height to the inner container ?
EDIT People are actually asking to close my question because it is "unclear". In case this wasn't obvious, I want the first snippet to stop shifting the text, and the second snippet to smoothly move the second div in place of the first one (without jumping).
Something like this, without the use of fixed sizes for the inner container
const div = document.querySelector('.toGo');
div.addEventListener('click', event => {
div.className += ' animate';
// Simulate Angular's DOM modification
setTimeout(() => div.style.display = 'none', 1100);
setTimeout(() => div.style.display = 'block', 1200);
setTimeout(() => div.className = 'toGo', 1300);
});
.toGo, .toStay {
height: 50px;
width: 100%;
background: coral;
transition: all 1000ms ease-in-out;
overflow: hidden;
}
.container {
height: 50px;
width: 100vw;
}
.toStay {
margin: 12px 0;
}
.animate {
height: 0;
width: 0;
opacity: 0;
}
<div class="toGo">
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
</div>
<div class="toStay">Lorem Ipsum</div>
<p>Click on the first div</p>
Your main issue in the first snippet was related to margin collapsing creating the jump effect. Consider a flexbox container to avoid margin collapsing:
you can then consider a clip-path animation combined with height animation (don't animate the width to avoid the shrink effect)
You can adjust the clip-path to control how the animation is done.