I've encountered an issue while trying to implement a transition on a child div within a 'parent' div that already has its own transition. It seems like the child transition is conflicting with the parent transition, causing it to end up in the wrong position.
What I'm aiming for is to have Child Container A slide out to the left and then have Child Container B slide into view from the right after Child Container A when a button is clicked.
You can see the problem replicated here: https://codepen.io/BONDJAMES/pen/mdegmMe
How can I achieve the desired effect of sliding out Child Container A to the left and having Child Container B slide in from the right after a toggle?
HTML
<div id="app">
<div class="viewBlocks">
<transition name="slide">
<div class="left" v-if="!MaxView">
<div class="subContainer">
<div class="container">
...
</div>
</div>
</div>
</transition>
<transition name="slide">
<div class="right">
<div class="subContainer">
<button @click="toggleBtn">Toggle</button>
Parent DIV
<div class="container">
<transition name="first-slide">
<div v-if="!showMiniB" class="miniContainerA">
<button @click="slideDivs">Slide A out - B In</button>
Child Container A
</div>
</transition>
<transition name="second-slide">
<div v-if="showMiniB" class="miniContainerB">
<button @click="slideDivs">Slide B out - A</button>
Child Container B
</div>
</transition>
</div>
</div>
</div>
</transition>
</div>
</div>
CSS
body {
margin: 0;
}
* {
box-sizing: border-box;
}
.viewBlocks {
display: flex;
}
.viewBlocks > * {
flex: 1 1 0%;
overflow: hidden;
}
.viewBlocks .subContainer {
margin: 10px;
background-color: white;
min-height: 200px;
padding: 1rem;
/* prevent text wrapping during transition? */
min-width: 300px;
}
.viewBlocks .left {
background-color: blue;
}
.viewBlocks .right {
background-color: red;
}
.viewBlocks .container {
background-color: white;
}
.slide-leave-active, .slide-enter-active {
transition: 1s cubic-bezier(0.5, 0, 0.3, 1);
}
.slide-leave-to, .slide-enter {
flex-grow: 0;
}
.miniContainerA{
border: green 3px solid;
text-align: center;
height: 60px
}
.miniContainerB{
border: pink 3px solid;
text-align: center;
height: 60px
}
.first-slide-enter {
opacity: 0;
transform: translatex(-100%);
transition: all 0.7s ease-out;
}
.first-slide-enter-to {
opacity: 1;
transform: translatex(0);
transition: all 0.7s ease-out;
}
.first-slide-leave-to {
opacity: 0;
transform: translatex(-100%);
transition: all 0.7s ease-out;
}
.second-slide-enter {
opacity: 0;
transform: translatex(0);
transition: all 0.7s ease-out;
}
.second-slide-enter-to {
opacity: 1;
transform: translatex(-100%);
transition: all 0.7s ease-out;
}
.second-slide-leave-to {
opacity: 0;
transform: translatex(0);
transition: all 0.7s ease-out;
}
.second-slide-leave {
transform: translatex(-100%);
}
VUE
var app = new Vue({
el: '#app',
data: () => ({
MaxView: false,
showMiniB: false
}),
methods: {
toggleBtn(){
this.MaxView = !this.MaxView
},
slideDivs(){
this.showMiniB = !this.showMiniB
}
}
})