Dynamic CSS with Custom Properties (aka CSS Variables) Transitions & Animations
Transcript from the "Transitions & Animations" Lesson
>> So, here do you remember this gallery where we were using scale and rotate to specify scale and rotate transform separately and we have this transition on hover. So, specifying a transition seems to work just fine here. But what if we want to specify different parameters for the scale transition and different parameters for the background transition?
[00:00:27] Right now we've just specified the time, which basically tells the browser, transition whatever you can transition, just make it last half a second. But if we want to provide separate parameters, we can actually specify different parameters for each property. So, for example, you see how the pictures become bigger when you hover, what if we wanted them to bounce as well?
[00:00:51] What if we wanted them to become a little bit bigger than snap back? We can actually do that with a custom cubic-bezier function. So, let's open cubic-bezier.com. And, if we have a cubic-bezier function that goes out of range, like it goes over 100% for the y-axis, that gives us a bounce.
[00:01:16] We can see it like this, see how it bounces. Let's copy it and we can actually modify the numbers themselves, to create a more intense bounce. Right now the bounce is a bit subtle, so I'm gonna specify 2 here. It's still a bit subtle, let's specify 3, okay, that gets us somewhere.
[00:01:43] So, notice that now because we're applying this cubic-bezier timing function to both of the things that are being transitioned, we get a bounce for both of them. Whereas we only wanted a bounce for the scale. A bounce looks kind of weird for the colors. We would never want colors to be bouncing like this.
[00:02:06] Let me show you again, when I hover the color goes to light yellow. But first, it goes to intense yellow because it's bouncing, and that looks really strange, do you see it? So, we don't want to use this bouncing cubic-bezier function for colors. So, let's instead specify individual parameters for each property that is being transitioned.
[00:02:37] So, we have the cubic-bezier for the scale and we have just five seconds and background and we're just gonna use the default, ease timing function for the background. I don't even need to specify it is the default. And notice that, now we're getting a transition for the color, but we stopped getting a transition for the scale anymore.
[00:03:02] What happened there, suddenly our code broke. So, what actually happened is explained if we look at the specification it, says and I quote CSS variables can even be transitioned or animated. But since the UA has no way to interpret their contents, they always use the flips at 50% behavior that is used for any other pair of values that can't be intelligently interpolated.
[00:03:29] So, how did we get a transition in the first place? Until we did this, we were actually getting a transition. This is because it wasn't the scale property that was being transitioned, it was the actual transform. Like if we scope this to the actual transform property, we'll get our transition again and it actually works fine, the colors are what we want and the bounce is what we want.
[00:03:58] But what if we actually wanted to only transition the scale property? What can we do in that case? So, the short answer is, if we wanted to work in every browser there's not much we can do. But if we're okay with using at property, we can just register it.
[00:04:21] If we register it, and we can't register it as an anything goes variable. We need to register it with an actual syntax, in this case a number. And give it an initial value and inherits, let's say false. Alright, yes, we don't want to give it an initial value of zero.
[00:04:54] An initial value of zero would make it entirely disappear. It's scale we want the initial value to be one, like no change. So now, even though we're animating the scale, we're transitioning the scale property, it works just fine. So, custom properties can trigger transitions but do not interpolate by default.
[00:05:25] However, registering the custom property can fix this, registered custom properties can interpolate. Here, we have an animation that goes from one color to another. And let's say we wanted to use our actual colors instead of repeating them in the keyframes, can we do that? So, That actually works just fine.
[00:06:02] Using a var function in keyframes or in values of properties, that works just fine. We don't need to register a property to be able to use the var function in keyframes. However, if what we were transitioning was, if we wanted to animate a property. Let's say we had a color property, and we would set it to accent color one here, And then we wanted to animate that property, And actually we don't even need it here let's just set background to var color.
[00:06:46] So, notice what happened here? Even though our code is functionally equivalent, suddenly we lost the animation. And instead we get this flips at 50% behavior. It just goes from yellow to turquoise with nothing in between. And this is because we are trying to animate a non registered property.
[00:07:10] Again, we can fix this by registering it, if we say property color, we give it a syntax. And we need the other descriptors as well. Let's say black for initial value and now everything's good again. So, to sum up, var in key frames works just fine but animating the actual properties requires registration.
[00:07:44] So, what can we do if we're okay with registering custom properties? A primary use case is animating gradients, often people want to animate a part of a gradient like the position of a color stop, a specific color on the color stop. In the past, there used to be a section in the images specification that tried to describe how gradients can interpolate.
[00:08:10] Like if you were trying to animate between two gradients, the browser would try to figure out how to do the animation intelligently. Now, most browsers never implemented this, the only implementation was Edge before it switched to Chromium. So, right now there is no implementation of gradient interpolation. However, this is where custom properties come in.
[00:08:32] Instead of this insane complexity of the browser trying to figure out how to animate two gradients, and us having to add dummy color stops to teach it how to animate two gradients. Instead we can actually code the animation however we want and avoid repetition by using custom properties.
[00:08:51] So, here we are trying to animate between these two gradients and obviously as you can see nothing's happening not much of an animation is happening. Because we can't animate between two gradients. But what if we use a custom property for the position which is the only thing that varies between these two gradients.
[00:09:12] Let's say, let's specify a p value, let's give it 0% here. And in the keyframe, we override p to 100% instead of repeating the gradient, and obviously we still don't get an animation because we haven't registered it. But once we register it, see what happens. So, we're gonna register it as a percentage, And set inherits to, let's set it to false and initial-value 0%.
[00:09:57] And notice how this beautifully animates now. I don't even need to set it here because we've set the initial value to 0%. If you look at the notes, there are also some links to resources where you can read more about cool things you can do with animating gradients.
[00:10:16] For example, one of these even includes an entire image reveal with slides, it's really cool. There's so many effects we can do basically by expanding this technique. And one thing to keep in mind, is that sometimes we may want to mirror CSS properties with custom properties to set multiple at once.
[00:10:47] For example, a common workaround for vendor prefixes is for example backdrop filter, which is what does the blurring behind this panel? So, backdrop filter still requires a prefix. In some browsers a webkit prefix, other browsers support the unprefix property. So ,instead of using autoprefix to add the prefixes automatically, or writing everything twice, we could use a custom property to set both at once.
[00:11:22] It's the same pattern we've seen before of using a custom property on the universal selector and setting it to initial so it doesn't inherit. However, this does have a problem. This does introduce a problem that was not there when we were just using the built in properties, let's say, We want to change this backdrop filter on hover.
[00:11:54] And make it blur more, let's say 20 pixels instead of say two pixels and let's add a transition for this, let's make it one second. And we're animating backdrop, oops backdrop filter. And note that this doesn't animate. And not only does this not animate, but even if we were okay with using that property to enable it to animate.
[00:12:24] We can't actually use that property here, because there is no syntax that describes the value space of backdrop filter. It's not a number, it's not a percentage, it's not an image, it's not a length. It's like it's none of these primitive values that we can specify there. In this individual, in this specific case, we can actually just apply the transition to everything and take advantage of the fact that custom properties can trigger transitions of other properties.
[00:12:57] Or if we wanted to explicitly filter out which properties the transition applies to. We would need to list all of them like backdrop-filter, webkit-backdrop-filter. And then this works again but we cannot actually animate dash dash backdrop filter. So, yes CSS variables enable you to set multiple properties at once and this is really cool but they do not interpolate.