最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Transition elements below a transitioned v-if - Stack Overflow

programmeradmin2浏览0评论

I have two elements, and the top one's visibility is controlled by a v-if on a simple boolean.

transition(name="fade")
    #element1(v-if="showFirst")
        p Foo

#element2
    p Bar

The first element is wrapped in a <transition> tag, exactly as per the Vue documentation.

However, while this does create a fading animation, the rest of the content on the page still jumps very jarringly.

How can I create a transition that will also smoothly transform the position of any and all siblings that follow?

A fiddle demoing this issue.

I have two elements, and the top one's visibility is controlled by a v-if on a simple boolean.

transition(name="fade")
    #element1(v-if="showFirst")
        p Foo

#element2
    p Bar

The first element is wrapped in a <transition> tag, exactly as per the Vue documentation.

However, while this does create a fading animation, the rest of the content on the page still jumps very jarringly.

How can I create a transition that will also smoothly transform the position of any and all siblings that follow?

A fiddle demoing this issue.

Share Improve this question edited Jul 13, 2022 at 22:59 tony19 138k23 gold badges277 silver badges346 bronze badges asked Jan 19, 2017 at 14:43 Emphram StavangerEmphram Stavanger 4,2149 gold badges38 silver badges66 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 13 +100

You need to use a transition-group and key your dynamic div and static div

<transition-group name="fade">
  <div v-if="switc" key="dynamic" class="animated">
     ...
  </div>
  <div key="main-content" class="animated">
     ...
  </div>
</transition-group>

And use this css classes

.fade-enter,
.fade-leave-active {
    opacity: 0;
    transform: translateY(-10px);
}
.fade-leave-active {
    position: absolute;
}

.animated {
  transition: all 0.5s;
  /*display: flex;*/
  width: 100%;
}

The real trick is to change position to absolute when leaving, then any other content can take correct position.

To know more about how Vue animate things please see this FLIP explanation post

And please see this working fiddle https://jsfiddle.net/bjfhth7c/4/

Edit

By mistake I did set display: flex; in .animated class, that was causing to every inner element to render in a strange way.

So now, I completely remove .animate class, and instead apply transition: all 0.5s and width:100% to every direct inner element of .wrapper

My final scss looks like this:

.wrapper {
  display: flex;
  flex-direction: column;
  >* {
    transition: all 0.5s;
    width:100%;
  };
}

.fade-enter,
.fade-leave-active {
  opacity: 0;
  transform: translateY(-10px);
}

.fade-leave-active {
  position: absolute;
}

Flex layout is a extend subject, but in short for this particular case flex-direction: column is arranging elements one bellows previous one.

If one of those elements has absolute position will be ignored in flex layout so any other elements will be redistributed on available space.

Please see this guide about flexbox and last working fiddle hope it helps.

You can use a slideDown/slideUp animation instead. For achieve this you don't need to know a height of a sliding element, the principles of max-height transition explained there.

So, as a result it will cause animated moving of elements below target.

Check out my example based on your fiddle.

vue js provides different transition classes, you have to use those properly to smooth the transition, I have tried with your example in this fiddle with some CSS, have a look.

.fade-enter-active, .fade-leave-active {
  transition: all .5s;
  height: 100px;
  opacity: 0.5;
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
  height: 0px;
  opacity: 0;
}

Some details from documentation:

There are six classes applied for enter/leave transitions.

  1. v-enter: Starting state for enter. Added before element is inserted, removed one frame after element is inserted.
  2. v-enter-active: Active state for enter. Applied during the entire entering phase. Added before element is inserted, removed when transition/animation finishes. This class can be used to define the duration, delay and easing curve for the entering transition.
  3. v-enter-to: Only available in versions >=2.1.8. Ending state for enter. Added one frame after element is inserted (at the same time v-enter is removed), removed when transition/animation finishes.
  4. v-leave: Starting state for leave. Added immediately when a leaving transition is triggered, removed after one frame.
  5. v-leave-active: Active state for leave. Applied during the entire leaving phase. Added immediately when leave transition is triggered, removed when the transition/animation finishes. This class can be used to define the duration, delay and easing curve for the leaving transition.
  6. v-leave-to: Only available in versions >=2.1.8. Ending state for leave. Added one frame after a leaving transition is triggered (at the same time 7. v-leave is removed), removed when the transition/animation finishes.

You can as well use CSS animations where you can provide on different phases of transition what will be your css property to make your transitions more smooth, like following and demo fiddle:

.fade-enter-active {
  animation: bounce-in .5s;
}
.fade-leave-active {
  animation: bounce-out .5s;
}
@keyframes bounce-in {
  0% {
    height: 5px;
  }
  30% {
    height: 30px;
  }
  50% {
    height: 50px;
  }
  100% {
    height: 100px;
  }
}
@keyframes bounce-out {
  0% {
    height: 90px;
    }
  50% {
    height: 50px;
  }
  100% {
    height: 0px;
  }
}
发布评论

评论列表(0)

  1. 暂无评论