2

I am using css transitions to lay out a bunch of divs on top of each other. At any point, one of the divs may collapse. And all of the divs below it are supposed to move up to fill its spot.

Here is a codepen that describes the situation.

The css I am using is the following:

div {
  height: 100px;
  width: 100px;
  margin: 15px;
}

.top {
  background-color: red; 
  transform-origin: top;
  animation: move 2s infinite;
}

.bottom {
  background-color: blue; 
}

@keyframes move {
  0% {
    transform: rotateX(0deg);
  }
  50% {
    transform: rotateX(90deg);
  }
}

With this, the top div will expand and contract. I want the divs below it to move up as the top one collapses.

If I switch transform for height, like this:

@keyframes move {
  0% {
    height 0;
  }
  50% {
    height: 100px;
  }
}

The bottom divs do move, but this is not a good solution for me because in the actual application, each div has a dynamically calculated size.

How can the bottom divs move smoothly with the top div?

Asons
  • 84,923
  • 12
  • 110
  • 165
Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148

1 Answers1

0

With transform you won't be able to do that, as when an element is transformed, the surrounding elements won't see any change in the DOM, as DOM-wise nothing have happened.


What you can do to optimize it all, is to prepare the browser that the height will change, with the property will-change: height

This new CSS property aim's to do what transform does, make smoother and more optimized animations.

Do note though:

will-change is intended to be used as a last resort, in order to try to deal with existing performance problems. It should not be used to anticipate performance problems.


Another possible solution (read hack), is to trick the browser to use GPU instead of CPU, shown in this answer (see its p.1):


Updated

In case of the height is auto, or similar, this will work with the max-height trick, and here is a couple of answers of mine, showing how-to:

And the last resort, if none of the above is applicable, is to use a small script and either create a styles dynamically (links below), or set them inline.

Asons
  • 84,923
  • 12
  • 110
  • 165
  • 1
    will-change looks interesting, but I don't see how it applies here. It looks like an optimization. In this case, if I use `will-change: height`, then do I need to also change the height property instead of using a transform? – Andrew Eisenberg Jul 16 '18 at 23:59
  • @AndrewEisenberg Yes, that is correct. With `will-change` you tell which property that _will change_, and then use that very same in your animation. – Asons Jul 17 '18 at 01:13
  • That won't work. As I mentioned above, the actual heights of the divs are dynamically determined. So, I can't use `height`, though I am looking at a solution that uses `max-height` instead. https://stackoverflow.com/questions/3508605/how-can-i-transition-height-0-to-height-auto-using-css – Andrew Eisenberg Jul 17 '18 at 04:17
  • @AndrewEisenberg Misunderstood you on that, and have now updated my answer to cover that angle as well, and a script one,.... so now all options should be covered :) – Asons Jul 17 '18 at 06:44
  • Thanks. In the end, we decided to use `max-height` with a fixed, large value. If this doesn't work out, we may move to a scripting solution where we calculate the height immediately before the animation starts, though we were hoping for a pure css solution. Since your suggestion is very close to what we wound up doing and since I learned quite a bit from your answer (even though I didn't use it directly) I will award you the answer. – Andrew Eisenberg Jul 17 '18 at 14:29
  • @AndrewEisenberg Great...and as it doesn't fully solved it for you, an upvote might be more appropriate than an accept. – Asons Jul 17 '18 at 14:31