Intro to CSS Transitions
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeForget about Vue for a few minutes. Instead, let's focus on how CSS transitions work by themselves. If you're already super familiar with CSS transitions, you rock. Feel free to jump to the next video. If not... let's go!
The Setup: Changing Opacity on Click
In shopping-cart.vue
, add a temporary div with some text inside: testing transitions. Also use the dynamic class syntax - :class
- to give this two classes: transition-testing
- a class it will always have - and hidden
, which it will only have when the currentState
is equal to checkout.
<template> | |
<div :class="[$style.component, 'container-fluid']"> | |
<div class="row"> | |
// ... lines 4 - 18 | |
<div class="col-xs-12 col-lg-9"> | |
// ... lines 20 - 21 | |
<div class="content p-3"> | |
// ... lines 23 - 49 | |
<div | |
:class="{ | |
'transition-testing': true, | |
'hidden': currentState === 'checkout' | |
}" | |
> | |
Testing transitions! | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
// ... lines 63 - 179 |
Down in the styles, add some CSS for this: .transition-testing
with opacity: 1
. That's... not actually necessary... because that's the default value, but it'll help make things more clear.
// ... lines 1 - 162 | |
<style lang="scss" module> | |
// ... lines 164 - 165 | |
.component :global { | |
// ... lines 167 - 170 | |
.transition-testing { | |
opacity: 1; | |
} | |
// ... lines 174 - 176 | |
} | |
</style> |
Then, when .transition-testing
also has the hidden
class, set opacity to zero.
// ... lines 1 - 162 | |
<style lang="scss" module> | |
// ... lines 164 - 165 | |
.component :global { | |
// ... lines 167 - 170 | |
.transition-testing { | |
opacity: 1; | |
} | |
.transition-testing.hidden { | |
opacity: 0; | |
} | |
} | |
</style> |
Basically, we're going to hide this element when we click the checkout button. Try it: there's the text and click the button. Gone! Back! Gone! Back! We're not using v-show
, but the result is, effectively, the same.
CSS Transitions!
CSS transitions allow us to... well to transition between certain CSS property changes. Right now, when the hidden
class is added, the opacity instantly changes from one to zero. But we can tell CSS to make that change slowly, like transitioning from one to zero over, let's say 3 seconds
To do that, on the class that the element always has, define that you want a transition to happen: transition: opacity
over 3s
.
// ... lines 1 - 162 | |
<style lang="scss" module> | |
// ... lines 164 - 165 | |
.component :global { | |
// ... lines 167 - 170 | |
.transition-testing { | |
transition: opacity 3s; | |
opacity: 1; | |
} | |
// ... lines 175 - 177 | |
} | |
</style> |
Check it out: when we click, the message slooowly fades out. How cool is that! I'm old enough to remember building page layouts with tables and rounding corners with images. This... is like winning the lottery.
There are a lot more things you can do with CSS transitions, but this is the basic idea. Back in our code, remove the opacity: 1
... just because it's redundant.
// ... lines 1 - 162 | |
<style lang="scss" module> | |
// ... lines 164 - 165 | |
.component :global { | |
// ... lines 167 - 170 | |
.transition-testing { | |
transition: opacity 3s; | |
} | |
// ... lines 174 - 176 | |
} | |
</style> |
Switching back to v-show
So... how does this relate to life in Vue? Back up in the template, find the temporary element and change it to use a proper v-show
: the way we normally hide and show things.
Copy the currentState === 'checkout'
line, change this to a boring class="transition-testing"
, and then add v-show=""
, paste, but now we need the reverse: show this when currentState === 'cart'
.
<template> | |
<div :class="[$style.component, 'container-fluid']"> | |
<div class="row"> | |
// ... lines 4 - 18 | |
<div class="col-xs-12 col-lg-9"> | |
// ... lines 20 - 21 | |
<div class="content p-3"> | |
// ... lines 23 - 49 | |
<div | |
v-show="currentState === 'cart'" | |
class="transition-testing" | |
> | |
Testing transitions! | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
// ... lines 61 - 177 |
When we try this... we lost our transition entirely! It hides and shows instantly. We can see the reason when we inspect the element: Vue hides and shows things by adding and removing display: none
. What we really need Vue to do is change the opacity from 1 to 0.
Let's talk about how Vue can do that next.