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.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Forget 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.

Leave a comment!

This course is also built to work with Vue 3!

What JavaScript libraries does this tutorial use?

// package.json
{
    "devDependencies": {
        "@fortawesome/fontawesome-free": "^5.15.1", // 5.15.1
        "@symfony/webpack-encore": "^0.30.0", // 0.30.2
        "axios": "^0.19.2", // 0.19.2
        "bootstrap": "^4.4.1", // 4.5.3
        "core-js": "^3.0.0", // 3.6.5
        "eslint": "^6.7.2", // 6.8.0
        "eslint-config-airbnb-base": "^14.0.0", // 14.2.0
        "eslint-plugin-import": "^2.19.1", // 2.22.1
        "eslint-plugin-vue": "^6.0.1", // 6.2.2
        "regenerator-runtime": "^0.13.2", // 0.13.7
        "sass": "^1.29.0", // 1.29.0
        "sass-loader": "^8.0.0", // 8.0.2
        "vue": "^2.6.11", // 2.6.12
        "vue-loader": "^15.9.1", // 15.9.4
        "vue-template-compiler": "^2.6.11", // 2.6.12
        "webpack-notifier": "^1.6.0" // 1.8.0
    }
}