How to make CSS transform affect the flow of other elements

I use CSS transitions with the transform property to compress elements when they are added or removed.

However, one of the problems is that this property does not affect the flow of other elements, so it seems that the deleted element is compressed, and then the remaining elements suddenly jump.

If I were to animate the height property instead of using a transform, that would be nice, however in real use I use variable height elements, so I won’t know what heights I can animate between them.


Edit: people suggested animating the height property (which won't work as described above), or the max-height . The max-height will work to some extent, however, you cannot precisely align the timings, since the transition will continue to adjust the max-height for the actual height of the element until the end of the transition period.

Another problem with these approaches is that it does not use the smooth animations that you can achieve with the transform property. The transformation of the object will occur smoothly, but the movement of the following elements stutters, as the browser makes these transitions in different ways.


Here's a JSFiddle with what I mean (try adding, then deleting elements, and see the transition when deleting elements):

 var button = document.querySelector("button"); var box = document.createElement("div"); box.className = "box"; box.appendChild(document.createTextNode("Click to delete")); button.addEventListener("click", function(e) { var new_box = box.cloneNode(true); new_box.addEventListener("click", function(e) { this.className = "box deleting"; window.setTimeout(function(e) { new_box.remove(); }, 1000); }); this.parentNode.appendChild(new_box); }); 
 button { font-size: 20pt; } .box { font-size: 20pt; margin: 10px; width: 200px; padding: 10px; background: pink; transform: scale(1, 1); transform-origin: top left; } .deleting { transform: scale(1, 0); transition: all 1000ms ease; } 
 <button> Add Box </button> 
+5
source share
3 answers

For elements whose layout is determined by the CSS window model, the transform property does not affect the flow of surrounding content of the transformed element.

REF: Rendering Conversion

You will need to use the max-height ( check this answer ) to get the desired effect.

 var button = document.querySelector("button"); var box = document.createElement("div"); box.className = "box"; box.appendChild(document.createTextNode("Click to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to deleteClick to delete")); button.addEventListener("click", function(e) { var new_box = box.cloneNode(true); new_box.style.height = ( Math.random() * (200 - 30) + 30 ) + 'px'; new_box.addEventListener("click", function(e) { this.className = "box deleting"; window.setTimeout(function(e) { new_box.remove(); }, 1000); }); this.parentNode.appendChild(new_box); }); 
 button { font-size: 20pt; } .box { overflow:hidden; font-size: 12pt; margin-bottom: 10px; width: 600px; max-height:1000px; padding: 10px; background: pink; transform: scaleY(1); transform-origin: top left; } .deleting { transform: scaleY(0); max-height:0; padding:0 10px; margin-bottom:0; transition: padding 1000ms ease,max-height 1000ms ease, transform 500ms ease 500ms, margin-bottom 1000ms ease; } 
 <button> Add Box </button> 
+1
source

You can create a wrapper around cutting boxes. Now you just scale the red rectangles, which means that it still uses the same space, but it scales. When you finally delete it, it will no longer use this space, the elements below it will jump up.

If you create a wrapper around each red rectangle, you can control the space that is required. Just change the height of this wrapper with the transition.

 /* css for a wrapper */ overflow: hidden; transition: height .2s; /* your time */ 

So, not only scale the red rectangles with the transition, but also put them in the wrapper element and change the height of the element.

0
source

For the best effect, you will need to change the properties of the box, which affect its environment. This includes width / height, padding, margins, and border width. In the example below, I set the appropriate properties to 0 for the desired effect. This includes all the properties that affect the vertical distance of the element: height , padding-[top/bottom] , margin-[top/bottom] and border-[top/bottom]-width all go to 0.

I also added box-sizing: border-box; and overflow: hidden; in the field - you should see what happens when they are not installed. I will let you know about them yourself.

 var button = document.querySelector("button"); var box = document.createElement("div"); box.className = "box"; box.appendChild(document.createTextNode("Click to delete")); button.addEventListener("click", function(e) { var new_box = box.cloneNode(true); new_box.addEventListener("click", function(e) { new_box.style.height = this.offsetHeight + 'px'; window.requestAnimationFrame(function () { new_box.style.height = 0; new_box.className = "box deleting"; window.setTimeout(function(e) { new_box.remove(); }, 1000); }); }); this.parentNode.appendChild(new_box); }); 
 button { font-size: 20pt; } .box { box-sizing: border-box; overflow: hidden; font-size: 20pt; margin: 10px; width: 200px; padding: 10px; border: 5px solid red; background: pink; transform: scale(1, 1); transform-origin: top left; } .deleting { height: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; border-top-width: 0; border-bottom-width: 0; transform: scale(1, 0); transition: all 1000ms ease; } 
 <button> Add Box </button> 
0
source

All Articles