-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Set "boundaries" for transitions at blocks #1480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for making this case. I definitely see where you're coming from. My own personal experience has been that the lack of nested transitions is a nuisance that forces me to employ unnecessarily 'creative' solutions, so my predisposition is to think that they should be the default. Of course, I haven't had as long to experience the reverse annoyance, since nested transitions have only been available a short while. It feels like someone coming to Svelte might find it less frustrating to have to figure out how to turn nested transitions off rather than figure out how to turn them on. I say that because it might not be obvious to someone why their nested transitions aren't running, and my own reaction would probably be to call it a bug. But i don't really know! I would love to hear from other folks to see if we can reach a consensus on what the correct default should be. |
Perhaps I'm completely wrong in my assumptions and haven't used nested transitions in the past because they weren't available. Though, as I think through my current app, I can't think of anywhere I would use it. If we make it easily flippable (e.g. a compiler option or root option) and pick a default, then we could see if there is a preference one way or the other with real use. If you feel the default should be |
Whether the default for child transitions is true or false, I would still like to make the case for having the boundaries for child transitions to be only be at the blocks. The |
Makes transitions only run when the closest non-component block containing them has changed state. Implements #1480. ### Details Without the `containedTransitions` compiler option, all transitions are run whenever their element is added/remove from the dom. With `containedTransitions` the transitions are only run when the closest non-component block (e.g. an if-block or each-block) changes state. This means the transitions on the items of an each-block will not run when the each-block first appears on screen, or when it is removed, but they will run when items are added/removed from the each block. In addition, if a whole page fades in with a transition at the page level, the there will not be other transitions occuring inside the page. The transition containers do not include components, since a component is a reusable container and not a state-driven block. Thus, a transition at the root of a component will run when that component is added to the DOM inside an if-block or each-block the same way an element with a transition inside either of those blocks is run.
Makes transitions only run when the closest non-component block containing them has changed state. Implements #1480. ### Details Without the `containedTransitions` compiler option, all transitions are run whenever their element is added/remove from the dom. With `containedTransitions` the transitions are only run when the closest non-component block (e.g. an if-block or each-block) changes state. This means the transitions on the items of an each-block will not run when the each-block first appears on screen, or when it is removed, but they will run when items are added/removed from the each block. In addition, if a whole page fades in with a transition at the page level, the there will not be other transitions occuring inside the page. The transition containers do not include components, since a component is a reusable container and not a state-driven block. Thus, a transition at the root of a component will run when that component is added to the DOM inside an if-block or each-block the same way an element with a transition inside either of those blocks is run.
Makes transitions only run when the closest non-component block containing them has changed state. Implements #1480. Without the `containedTransitions` compiler option, all transitions are run whenever their element is added/remove from the dom. With `containedTransitions` the transitions are only run when the closest non-component block (e.g. an if-block or each-block) changes state. This means the transitions on the items of an each-block will not run when the each-block first appears on screen, or when it is removed, but they will run when items are added/removed from the each block. In addition, if a whole page fades in with a transition at the page level, the there will not be other transitions occuring inside the page. The transition containers do not include components, since a component is a reusable container and not a state-driven block. Thus, a transition at the root of a component will run when that component is added to the DOM inside an if-block or each-block the same way an element with a transition inside either of those blocks is run. Intro and outro transitions will run unless `intro` or `outro` on the transition object (e.g. next to duration/delay) are set to false. Transition defaults can be set in the root options, including intro and outro.
Allows transitions to skip running when they are added to the DOM or removed from it. Similar to the compiler option `skipIntroByDefault` this allows the intro/outro to be skipped. Example: ```html {#if visible} {#each things as thing} <div transition:fade></div> {/each} {/if} <script> export default { transitions: { fade(node, params) { return { intro: false, outro: false, duration: 400, css: t => { return `opacity: ${t}`; } }; } } }; </script> ``` In this example items in the each-block will fade in and fade out when they are added to or removed from `things` but the list will appear suddenly and disappear suddenly (no fade) when `visible` is toggled to `true` or `false`. This is another try at #1480 from the compiler option in #1692. Intro and outro transitions will run unless `intro` or `outro` on the transition object (e.g. next to duration/delay) are set to false. Transition defaults can be set in the root options, including intro and outro.
Allows transitions to only run locally, skipping running when they are added to the DOM or removed from it. Example: ```html {#if visible} {#each things as thing} <div transition:fade|local></div> {/each} {/if} <script> export default { transitions: { fade(node, params) { return { duration: 400, css: t => { return `opacity: ${t}`; } }; } } }; </script> ``` In this example items in the each-block will fade in and fade out when they are added to or removed from `things` but the list will appear suddenly and disappear suddenly (no fade) when `visible` is toggled to `true` or `false`. This is another try at #1480.
Pulled from #1431 (comment) and opened here as a new issue for further discussion
Note: The following opinions are coming from a view that animations and transitions are most often used in web apps to call attention to changes in a page that is already loaded, and that the area of the page handling the change should be the one defining the transition. For example, the part that deals with changing the entire page in a SPA as you navigate might fade the entire page in (or might choose not to employ any transition), but elements on the page wouldn't fade themselves in unless their data was not loaded at the initial transition, in which case they might fade in after their portion of the data was loaded. Coordinating transitions throughout a page to run together should still be possible for advanced effects but should not be the default.
Addressing this comment #1431 (comment):
Allowing child transitions to run will give fine-grained control and allow more robust use-cases. However, the vast majority of the time this will not be used. I propose the default be
childtransition:false
andchildtransition:true
be used instead for those cases when you want the lower animations to run.I believe transition boundaries should be at the block level with
EachBlock
,AwaitBlock
andIfBlock
(including else of course). I don't think it should be atComponent
because a component with a transition at the top level (not inside a block) would have the expectation that the transition is run when the component is placed within anif
/each
using the same rules that an HTML element would within thatif
/each
(e.g. skipping the intro/outro when first being added/removed).The default rule of thumb should be,
transition
is tied to theif
/each
nearest it. It should not run (unless explicitly told to do so with an override) when thatif
/each
is first inserted into the DOM or when it is removed, only when the value for theif
/each
changes and elements are added/removed.If you want transitions to run across these boundaries then you can use
childtransition:true
. This would be necessary even if e.g. the outerif
didn't have a transition. E.g.This allows the most expected behavior to be default and prevents confusion that would otherwise prevail when changes in an app (route changes and other large and small changes) cause animations to run unexpectedly.
I believe this is the correct behavior for the majority of web apps and that the directives for
childtransition:true
andskipintro:false
andskipoutro:false
will be rarely used and only in special circumstances.The text was updated successfully, but these errors were encountered: