添加第3个元素时,过渡组动画会更改行为

bgd*_*mhl 8 html javascript css transition vue.js

上下文:我div在页面的顶部显示/隐藏按钮.的div是按钮下和内容的上方.我已经习惯transition-group了其余内容div在显示/隐藏时向上/向下滑动.内容有一个margin-top限制自己从div显示/隐藏的上述内容.

需要:我想要一个上边距,div这样当它显示时,它会保留自身和按钮之间的空间. https://imgur.com/UG5iakC

问题:我尝试了两种方法:

1)在隐藏处放置边距顶部div. 因为我position:absolutediv隐藏,当它使内容得到过divdiv大小调整为内容的大小,所以Margin获取自动变小; 因此,当隐藏它时,边缘会在隐藏之前变小,而且很难看. GIF:https://gph.is/2QInDfj

2)添加hr上面的div,里面的transition-group.没有它hr,幻灯片就像预期的那样工作div.但是,当我加入hr并点击隐藏div,滑动发生,正如预期,但divhr瞬间消失,而不是它在显示和内容滑过并覆盖它. GIF:https://gph.is/2yd4JGt

期望的视觉效果没有保证金/小时:https: //gph.is/2OPZyFV

HTML

<transition-group name="slide">
    <hr class="m-0" v-if="isVisible" key='h'>
    <div class="d-flex" v-if="isVisible" id="filters" key='x'>
        <div class="pl-5">
            <p class="filterTitles">Day</p>
            <app-day-filter v-for="day in weekDay" 
                :key="day.index" 
                :day="day">
            </app-day-filter>
        </div>
        <div class="pl-5">
            <p class="filterTitles">Time of day</p>
            <app-tod-filter v-for="todf in tod" 
                :key="tod.index" 
                :todf="todf">
            </app-tod-filter>
        </div>
    </div>
    <app-event v-for='(eveniment, index) in filterEvent' 
        :key='index' 
        :eveniment='eveniment' 
        :index='index'></app-event>
</transition-group>
Run Code Online (Sandbox Code Playgroud)

CSS

.slide-enter {
    opacity:0;
}
.slide-enter-active {
    transition: all 1s ease-out;
}
.slide-leave-active{
    transition: all 1s ease-out;
    opacity: 0;
    position: absolute;
}
.slide-move {
    transition: transform 1s;
}
#filters {
/* border-top: 1px solid lightgrey; */
}
Run Code Online (Sandbox Code Playgroud)

建议?

谢谢

jac*_*arm 1

这主要是 CSS 问题。

如果该元素被引入到, andhr内的布局中,则 CSS 属性与, and ,相关,并且在该状态期间被设置为(这将导致该元素从其先前在布局流中的相对位置“消失”) ,那么许多元素和属性将同时转换,从而导致不良效果。 transition-grouptransitionallpositionabsoluteleave-active

但是,考虑到该问题寻求一个没有和顶部的margin解决方案,并假设该按钮有一个事件处理程序,如下所示:hrtransition-group

<button class="filter-button" v-on:click="toggleSlider">Filters</button>
Run Code Online (Sandbox Code Playgroud)

该函数toggleSlider将切换isVisible动画过渡所依赖的属性:

methods: {
  toggleSlider() {
    this.isVisible = !this.isVisible;
  }
}
Run Code Online (Sandbox Code Playgroud)

使用CSS,而不是转换all,只需转换将实现所追求的效果的属性,即,opacity并且通过这个答案,max-height。通过完全删除绝对定位,并使用相对位置加上 z 索引和以下 CSS,可以达到预期的效果。

/* put margin spacing on the bottom of the button */
.filter-button {
  margin-bottom: 25px;
}

/* add relative positioning to enforce z-indexing */
.filter-group {
  position: relative;
  z-index: 1;
}

/* add relative positioning to enforce z-indexing */
.filter-content {
  position: relative;
  z-index: 2;
}

/* hidden states */
.slide-enter,
.slide-leave-to {
  opacity: 0;
  max-height: 0px;
}

/* shown states - max-height can be adjusted as desired */
.slide-enter-to,
.slide-leave {
  opacity: 1;
  max-height: 300px;
}

/* while animating during animation entry phase */
.slide-enter-active {
  transition: opacity 0.75s ease-in, max-height 0.5s ease-out;
}

/* while animating during the animation departure phase */
.slide-leave-active {
  transition: opacity 0.75s ease-out, max-height 0.5s ease-out;
}

/* add padding to bottom of filters section */
.pl-5 {
  padding-bottom: 25px;
}
Run Code Online (Sandbox Code Playgroud)

通过在按钮和过滤器部分的底部添加边距,可以保留部分之间的间距。

我创建了一个CodeSandbox来说明此解决方案。