Reputation: 8492
I'm creating a slider element of 2 items only. I want them to smoothly slide back and forth to the left and right when I click back / next. It works well when I click next, elements scroll and fade, but when I click back, the first element jumps ahead in time no matter what I do, this gif explains a bit more visually:
Edit: Here is a fiddle - http://jsfiddle.net/eywraw8t/273583/
This is my css:
.first-slide-enter{
opacity: 0;
transform: translatex(-100%);
transition: all 1.5s ease-out;
}
.first-slide-enter-to{
opacity: 1;
transform: translatex(0);
transition: all 1.5s ease-out;
}
.first-slide-leave-to{
opacity: 0;
transform: translatex(-100%);
transition: all 1.5s ease-out;
}
.second-slide-enter{
opacity: 0;
transform: translatex(0);
transition: all 1.5s ease-out;
}
.second-slide-enter-to{
opacity: 1;
transform: translatex(-100%);
transition: all 1.5s ease-out;
}
.second-slide-leave-to{
opacity: 0;
transform: translatex(0);
transition: all 1.5s ease-out;
}
This is my html:
<transition name="first-slide">
<div v-if="!newShortcut.link">
<div id="drop-shortcut" class="drag-file clickable" @click="addShortcut">
<i class="fas fa-file-upload fa-lg"></i>
<p style="margin:20px 0 0;">Drag file here
<br> or click to browse</p>
</div>
<div>
<button @click="newShortcut.link = !newShortcut.link">Next</button>
</div>
</div>
</transition>
<transition name="second-slide">
<div v-if="newShortcut.link">
<div id="drop-icon" class="drag-file" @click="">
<i class="far fa-file-image fa-lg"></i>
<p style="margin:20px 0 0;">Drag file here
<br> or click to browse</p>
</div>
<div>
<button @click="newShortcut.link = !newShortcut.link">back</button>
</div>
</div>
</transition>
How to make this work?
Upvotes: 0
Views: 2358
Reputation: 3551
So @Julian is correct for the blocking issue, but there is another way to fix it that might work for you better. See this fiddle : http://jsfiddle.net/xcmn76Lo/
Basically what was needed was some tweaking to the second slide. There is a hook you can use similar to enter
to specify where it starts leaving from. In this case since the other div reserves its space immediately, you need to start the leave transition offsetting appropriately.
.second-slide-leave{
transform:translatex(-100%);
}
Then instead of transition to 100%, set leave-to
to 0 (aka where it WOULD end up if moved over by the incoming div).
.second-slide-leave-to{
opacity: 0;
transform: translatex(0);
transition: all 1.5s ease-out;
}
Upvotes: 1
Reputation: 3719
The issue was because of how your elements are displayed. Each slide is a block
, so it occupies a space in your layout.
So when you were at the second slide and click the back button. What happens before that is, there was no slide 1 in the layout and when vue starts to insert the slide 1 back, it occupies a space which causes the second slide to suddenly jump from left to right.
So to fix that behavior, you can make each slide's position as absolute
so that if they are inserted back, they will not cause such behavior because absolute
position will not affect it's neighboring element's position unlike the relative
position.
#app>div {
position: absolute;
height: 200px;
width: 200px;
text-align: center;
left: 0;
top: 0;
}
and update the css transition for the second slide a little bit:
.second-slide-enter {
opacity: 0;
transform: translatex(100%);
transition: all 1.5s ease-out;
}
.second-slide-enter-to {
opacity: 1;
transform: translatex(0);
transition: all 1.5s ease-out;
}
.second-slide-leave-to {
opacity: 0;
transform: translatex(100%);
transition: all 1.5s ease-out;
}
Here's the full JS Fiddle: http://jsfiddle.net/eywraw8t/273631/
Upvotes: 1