5

I have two divs that i transition between using transition-group, which works as it should - however, the content below the divs transitioning, is "jumping" depending on the height of the divs. What I want it that jumping being prevented, and instead it animates somehow, so I get a nice smooth transition when switching between elements without it "pushing" down to content with a "jump"..

Hope it makes sense :)

I've setup an example on codesandbox here: https://codesandbox.io/s/reverent-stallman-8ixhp?file=/src/components/HelloWorld.vue

The template looks like:

<div class="hello">
    <button @click="groupShowOne">Show first {{ gShowFirst }}</button>
    <button @click="groupShowTwo">Show second {{ gShowSecond }}</button>
    <transition-group name="fade-group" tag="div" mode="out-in" appear>
      <div
        class="group-element"
        v-if="gShowFirst"
        style="background-color: yellow"
      >
        <h3>This is a headline</h3>
        <p>This is a text</p>
      </div>
      <div
        class="group-element"
        v-if="gShowSecond"
        style="background-color: red"
      >
        <h3>
          This is a headline <br />This is a headline <br />This is a headline
          This is a headline This is a headline This is a headline
        </h3>
        <p>
          This is a text This is a text This is a text This is a text This is a
          text v This is a text v <br />This is a text This is a text This is a
          text This is a text This is a text v This is a text v <br />This is a
          text This is a text This is a text This is a text This is a text v
          This is a text v
        </p>
      </div>
    </transition-group>
    <div style="background-color: blue; min-height: 500px; color: #FFF">
      Prevent this div from jumping<br />
    </div>
  </div>

The animation looks:

<style scoped>
.group-element {
  width: 100%;
  min-height: 100px;
  max-height: 20000px;
  transition: all 0.5s;
}
.fade-group-enter,
.fade-group-leave-to {
  opacity: 1;
}
.fade-group-leave-active {
  opacity: 0;
  position: absolute;
}
</style>
viewist
  • 77
  • 1
  • 7

2 Answers2

1

Try this

  1. Setting the transition property in the passive div:
.ele {
  background-color: blue;
  min-height: 500px;
  color: #fff;
  -moz-transition: all 0.5s;
  -ms-transition: all 0.5s;
  -o-transition: all 0.5s;
  -webkit-transition: all 0.5s;
  transition: all 0.5s;
}
  1. Let it do some animation
eleStyle() {
  return {
    transform: this.gShowSecond ? "translate3d(0, 100px, 0)" : "none",
  };
},

The div:

<div class="ele" :style="eleStyle">Prevent this div from jumping<br /></div>
Chris Wong
  • 564
  • 4
  • 4
  • But this makes it depend on setting a fixed translateY size, which in my case can be very dynamic.... I dont always know the value, so unfortunately cant to this.. :/ – viewist May 02 '21 at 09:26
  • Also, the div below (the prevent this from jumping div), i dont always know which element this is or can be, which makes it very hard to handle.... Can be anything actually, which requires I need to add a transition to every possible known / unknown element, which isn't ideal :/ – viewist May 02 '21 at 09:29
  • So I guess, in my case, it would be the wrapping div (fade-group) that would need to have transition height, but I cant get that to work :( – viewist May 02 '21 at 09:30
  • @viewist, did you find any smart solution for this at the end? This use case seems extremely usual to me, but I could not find almost information about it searching on the Internet by june 2023... :S – andcl Jun 25 '23 at 11:33
0

What you can try:

  1. Vue has a *-move class for group transitions. However, the transition-group has to be applied to all the elements including the one that has the v-move class, to work.

  2. You could still work with what you have and dynamically bind a separate CSS transition for the blue box when showSecond or showFirst equate to a certain value.

Soviut
  • 88,194
  • 49
  • 192
  • 260
MT_dev
  • 163
  • 1
  • 10
  • Any reference like a documentation link to `v-move`? First time i'm hearing of it and Google search comes up empty – kano Jan 11 '23 at 09:57
  • 1
    @kano it's a `*-move` class, not a directive. I've edited their answer to include that and an updated link to the exact example in the docs of how to use it. – Soviut Feb 20 '23 at 22:25