Even though you are concerned that using transforms could have a negative performance, I think that the opposite is true.
Bear in mind that other solutions involve massive reflows, that probably are more performance intensive on the CPU (transforms most probably are handled by the GPU).
However, solving this with this with transforms is a little bit hard to code. Specially changing the amount of pixels that need to be moved, and injecting them into the style.
See a posible solution. I have used just JS to make it more portable.
If you are concern about performance, the result of findKeyframesRule could be assigned to a variable and reused.
document.addEventListener('DOMContentLoaded', setEvent, false);
function setEvent() {
var elements = document.getElementsByClassName('element');
for (var n = 0; n < elements.length; n++) {
elements[n].addEventListener('click', remove, false);
}
}
function remove(event) {
var current = event.currentTarget;
var elements = document.getElementsByClassName('move');
for (var n = 0; n < elements.length; n++) {
elements[n].classList.remove('move');
}
window.setTimeout(function() {
remove2(current);
}, 0);
}
function remove2(current) {
var next = current.nextElementSibling;
if (!next) {
return;
}
var top1 = current.offsetTop;
var top2 = next.offsetTop;
var diff = top2 - top1;
var newTransform = 'translateY(' + diff + 'px)';
var rule = findKeyframesRule('move');
var style = rule.cssRules[0].style;
style.transform = newTransform;
next.classList.add('move');
current.style.height = '0px';
}
function findKeyframesRule(rule) {
// gather all stylesheets into an array
var ss = document.styleSheets;
// loop through the stylesheets
for (var i = 0; i < ss.length; i++) {
var ss1 = ss[i];
// loop through all the rules
if (!ss1.cssRules) {
alert('you are using Chrome in local files');
return null;
}
for (var j = 0; j < ss1.cssRules.length; j++) {
// find the keyframe rule whose name matches our passed parameter
if (ss1.cssRules[j].type == window.CSSRule.KEYFRAMES_RULE && ss1.cssRules[j].name == rule)
return ss1.cssRules[j];
}
}
return null;
}
.element {
position: relative;
width: 200px;
overflow: hidden;
}
.element>div {
margin: 5px;
padding: 20px;
background: rgb(150, 200, 250);
}
.move,
.move~.element {
animation: move 2s;
}
@keyframes move {
from {
transform: translateY(60px);
}
to {
transform: translateY( 0px);
}
}
(click to remove)
<div class="element">
<div>
Element 1
</div>
</div>
<div class="element">
<div>
Element 2
<br>Second line
</div>
</div>
<div class="element">
<div>
Element 3
</div>
</div>
<div class="element">
<div>
Element 4
<br>Second line
</div>
</div>
<div class="element">
<div>
Element 5
</div>
</div>