Grouping CSS @keyframes rules

2019-06-20 05:25发布

问题:

I completely understand that you cannot group animation keyframes selectors such as

@keyframes,
@-moz-keyframes,
@-webkit-keyframes { /*do something*/ }

and that you absolutely MUST do

@keyframes { /*do something*/ }
@-moz-keyframes { /*do something*/ }
@-webkit-keyframes { /*do something*/ }

I know there are pre-processors that can do all this for me. But I am more interested in the reason behind why this is the case?

My google-fu is failing me. It seems to always direct me to a stackoverflow page telling someone they 'cannot' do it and they must separate them all out, or telling people about the pre-processors -or- I get sent to that horrible about.com and read stuff like

  • Any Selector Can be Grouped ~about.com

Which obviously is not true in this case. If someone can direct me to an article, or explain to me why it cannot be grouped it would be most helpful.

回答1:

Keep in mind that at-rules and selectors are completely different things.

At-rules are covered in this section of CSS2.1 spec, which says that an at-rule consists of exactly one at-keyword followed by some statement (be it a semicolon-terminated statement, or a block). As far as the CSS parser is concerned, what you have is a set of three separate at-rules, one prefix for each vendor and one unprefixed rule for the standard.

The more appropriate counterpart to at-rules would be rule sets, or style rules, described here. A rule set consists of a selector and a declaration block (containing style declarations). This is analogous to the contents of an at-rule as described above. It also means that the selector is just one part of a rule set.

Certain at-rules do allow comma-separated values in their preludes, such as @media:

@media screen, projection {
    /* Styles for both screen and projection media */
}

But instead of grouping the at-rules in entirety, the grouping happens within the value that comes after the at-keyword in the beginning of the rule.

This @media rule can be expanded into two separate rules like so:

@media screen {
    /* Styles for screen media */
}

@media projection {
    /* Styles for projection media */
}

Notice that each rule has its own @media at-keyword.

Similarly, when you group multiple selectors into a single rule, what you have is one style rule. The part that is grouped is the selector; everything in the declaration block that follows applies to all the selectors that are listed in the group:

.foo, .bar {
    /* Styles that apply to both .foo and .bar elements */
}

And when you expand it, it becomes two rule sets:

.foo {
    /* Styles that apply to .foo elements */
}

.bar {
    /* Styles that apply to .bar elements */
}


回答2:

Because of

When a user agent cannot parse the selector (i.e., it is not valid CSS 2.1), it must ignore the selector and the following declaration block (if any) as well.

found at http://www.w3.org/TR/CSS21/syndata.html#rule-sets


So each vendor prefix makes the whole rule un-parseable for all the other vendors.