Search code examples
cssanimationchaining

animation: shorthand property vs animation-name:


I've searched everywhere to find an answer to this question but I couldn't.

My question is about the shorthand animation property vs the long way around.

When you want to chain two animations together you cannot do the following

animation-name: keyframename1 1s, keyframename2 3s;

that will not work, but if you do the following by dropping the -name it works.

animation: keyframename1 1s, keyframename2 3s;

I cannot find any information online anywhere why you need to drop the name part from the selector for it to work. I understand it's a shorthand property, but doesn't seem to be a long winded way of including 2 keyframes to work one after the other.

Because soon as you declare animation-name: it will only take the first keyframe name and ignore the second one. But animation: is supposed to be for combining various selectors for one keyframe. Not for combining multiple keyframe names.

How would you include two keyframe names to work one after the other without doing it the shorthand way? Is it possible to use the selector of animation-name:? And why doesn't the W3C website explain you can actually chain keyframe name(s) in the shorthand property and not just transition selectors etc.


Solution

  • The MDN article is very insightful, in my opinion.

    The problem is that when you specify the animation-name only, you cannot specify the duration as well. Thus, your suggested rule

    animation-name: keyframename1 1s, keyframename2 3s; /* this won't work! */
    

    is invalid syntax. Your browser may interpret this as "let's only apply animation keyframename1", but at least in Firefox the rule is ignored altogether. I would expect that behavior, actually.

    Your second rule is valid and will indeed apply both animations. This is because the animation directive will take a list of animations, each one including a name and duration. You can specify even more, like the animation-timing-function, animation-iteration-count and animation-fill-mode. Values that you do not specify are set to a default value.

    This last remark is important! When you write the following

    animation-duration: 10s; /* this will be overwritten by the next line */
    animation: keyframename1;
    

    The duration will be 0s, because that is the default value of animation, as you can see in the linked article.

    The aforementioned specific directives each take a list as well. So, if you want to apply more than one animation, you can either specify both of them fully in a single animation rule, or set all their properties separately using the other directives.

    The following snippet illustrates both methods. You can see that the result is exactly the same.

    @keyframes fly-down {
      from { top: 0; }
      to { top: 100px; }
    }
    
    @keyframes fly-right {
      from { left: 0; }
      to { left: 100px; }
    }
    
    div {
      display: inline-block;
      position: relative;
      padding: 20px;
      border: 1px solid #000;
    }
    
    div.method1 {
      animation-duration: 1s, 3s;
      animation-fill-mode: both;
      animation-name: fly-right, fly-down;
    }
    
    div.method2 {
      animation: fly-right 1s both,
                 fly-down 3s both;
    }
    <div class="method1">Hi!</div>
    <div class="method2">Hi!</div>