Svelte Fundamentals

Svelte Fundamentals Key Blocks, Deferring, & Animate

Check out a free preview of the full Svelte Fundamentals course:
The "Key Blocks, Deferring, & Animate" Lesson is part of the full, Svelte Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Rich demonstrates replacing the contents of key blocks on value change, coordinating transitions between multiple elements by deferring transitions, and applying motion to elements that are not transitioning using animate.

Get Unlimited Access Now

Transcript from the "Key Blocks, Deferring, & Animate" Lesson

[00:00:00]
>> Let's talk about key blocks. So ordinarily, elements are just there in the DOM. And if you change the value inside them, you're not gonna play transitions, which might not be what you want. So here we have a typewriter transition that we want to run on the text as the text changes.

[00:00:22] Every time we get a new message, we want the typewriter to play it in. And in order to do that, we need to remove the element from the DOM and then put a new one in. And we do that with something called a key block. Key will take some value, and whenever that value changes, the contents of the key block will be replaced altogether.

[00:00:43] So let's just put that around this paragraph element here. You'll now see that when that i value changes on an interval, we're getting rid of the existing paragraph and creating a new paragraph with a new typewriter transition Finally, a particularly powerful aspect of Svelte's transitions is the ability to defer them so that they can, in effect, talk to each other.

[00:01:23] Here we have a pair of todo lists. We have a list of to-dos that have yet to be done and we have a list of to-dos that have been done. And if I toggle one of these items, then it will just move to the other list because that's how we've set this up.

[00:01:38] We have inside our app, we have a TodoList, which is done=(false). And in TodoList, we've done=true, and the todos themselves are in this store that we have, which is coming from todos.js. And in the real world, things don't behave that way. Things don't disappear from one place and reappear in another.

[00:02:02] In the real world, things move from one place to the other. And it's nice if we can get a little bit of that real world physicsness in our user interfaces, because using motion can help users understand what's actually happening in your app. And we can achieve this in Svelte using something called the crossfade transition.

[00:02:23] If we open the transition.js module, you'll see that we're importing crossfade from Svelte transition the same place that we got fade and fly and slide and so on, and we're also importing an easing function. And we're creating a pair of transitions called send and receive, by calling this crossfade function.

[00:02:44] We're also specifying a fallback, which could be anything, it could be a transition that you imported from Svelte transition. And then inside the TodoList.svelte, we can use those send and receive transitions to control what happens when those elements are added and removed. We're gonna begin by importing them from that module.

[00:03:16] And then down here inside the TodoList, we'll add the in and out transitions on the list item. So when an element enters the DOM, we're gonna receive the element. And we're gonna give it a key, which is the unique idea of the todo. And similarly, when it leaves the DOM, we're gonna send it to the other todoList.

[00:03:53] And so now when we toggle these values, it actually moves from one list to the other. The reason that we're creating send and receive in this separate module over here, instead of doing it inside the todoList itself, is because we have two todoLists. And so if we created the send and receive functions inside the todoList, then send and receive would only be able to talk within a todoList.

[00:04:19] But because they're in this external module, the two components can coordinate their transitions with each other, based on the key that we parse in when the element is added or removed. Now, if you're paying close attention to happenings in the web development world, you'll know that there is in fact a view transition API coming to the platform.

[00:04:42] It's available in Chrome already, other browsers, hopefully, will add it soon. And so eventually, you might be able to do this just with CSS. But for right now, I recommend using something inside Svelte, because this way you'll get a consistent user experience whatever browser your user is using.

[00:05:04] Okay, so just now we were using transitions to move things from one side to the other. That's great, except that I don't really like this popping effect, that when I move that first todo, the other ones just kind of pop into place, which is the exact opposite of what we're trying to achieve here.

[00:05:23] So we need to apply motion to the elements that are not transitioning in and out of the DOM, the elements that are staying in the same list but are moving positions. And so for this we can use something called the animate directive. You need animate with a flip function, which stands for first last invert play, which is a technique that allows us to do smooth motion entirely with CSS transitions.

[00:05:58] And once we've imported that, we can add it to the list item where we previously added the transitions, just like this animate, flip. The now when we toggle these values, the list moves smoothly. It's a little bit too slow though, it's not a very satisfying effect, so we'll customize that with a duration of 200 milliseconds.

[00:06:30] Now one thing that you will want to be conscious of when you're using this in your own apps is that some users prefer not to have motion in their apps. And so we can add a prefers reduced motion setting, that sets the duration to zero. You can also parse a function for the duration so that the actual number of milliseconds will be determined by the number of pixels that the element has to move, if that's more in line with the effect that you're trying to achieve.