Search code examples
htmlcssw3cfeature-detection

How can an @supports rule support name of animations in this statement?


I found this CSS on a page in the W3C and I don't know how it makes any sense, specifically the animation name part:

@supports ((transition-property: color) or
           (animation-name: foo)) and
          (transform: rotate(10deg)) {
  // ...
}

I understand this supports rule:

@supports (display: grid) {
  .main {
    display: grid;
  }
}

It means: if the browser supports the "grid" display type, then apply this rule. But what I don't understand is when the first example says animation-name: foo.

To me, that means: if the browser supports an animation with the name "foo", then apply this rule. I thought you (the developer) defined animations. Is it just a bad example?

Here is the documentation on animation-name. You define the animation name when you define a keyframe. So is it just saying: "Enable this query when someone has defined a keyframe rule with the name foo"? That would mean not whether there's "support" for an animation named "foo", but rather whether there exists an animation named "foo".

https://www.w3.org/TR/css3-conditional/#processing


Solution

  • That means if the browser supports an animation with the name "foo" apply this rule. I thought you the developer defined animations. Is it just a bad example?

    That's not really what it means. The difference between display and animation-name is that the first one takes a value in a set of predefined values, whereas the second one takes any valid string.

    In the CSS specification, you can find the exhaustive list of values allowed for display. You are obliged to use a valid value, which is logical, and the support for different values isn't the same.

    animation-name takes a value called <keyframes-name> and from the specification we have:

    <keyframes-name> = <custom-ident> | <string>
    

    and

    Some properties accept arbitrary author-defined identifiers as a component value. This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier that would not be misinterpreted as a pre-defined keyword in ... ref

    Strings are denoted by and consist of a sequence of characters delimited by double quotes or single quotes. ref

    The property can take an infinite number of values and you are obliged to use a valid one, so any string will do the job (like foo). Since there is no support based on the value used, all of them will have equal support; that's why using a random string is OK to test the support of animation-name.

    The logic is the same for al; you have to use a valid value, and then we test the support of this value. For display, you are restricted to some values and each one has different support between browsers. For animation-name, you have no restriction on the value and all of them have the same support.

    If you try to use an invalid value for animation-name, it won't work:

    @supports (animation-name: a b ) {
      body {
        background:red;
      }
    }

    same as using an invalid value for display:

    @supports (display: 0 ) {
      body {
        background:red;
      }
    }


    The same logic applies to transition-property; that can take a <custom-indent> as value.


    if you use a valid value for animation-name (even if the animation doesn't exist) and a valid value for transition-property (even if the property doesn't exist), then it will apply:

    @supports ((animation-name: myanimation) and (transition-property:a-random-name)) {
      body {
        background:green;
      }
    }