Re: [csswg-drafts] [css-cascade] Additive CSS

General thoughts on the `!add` proposal:

This is one of the most straight-forward proposals I've seen for allowing partial or additive CSS declarations, which is a definite bonus.  It fits nicely into CSS syntax (finally something else that uses `!qualifier`).  And it directly builds on CSS cascading.

The main thing that would need to be worked out is the addition rules for different data types.  This would be similar to how we have interpolation rules for data types -- and with the similar understanding that some things can't be added and would be replaced instead.

The simplicity could be a limitation when talking about more complex properties.  For property values that consist of more than a single value, there usually wouldn't be a single universal way to define how to add two declarations.  

For some cases, this issue could probably be avoided if you could build up that complex value from custom properties, and then animate the custom property values in an additive way.  This could be a solution to Brian's filter example.  Normally, filters could add by adding an extra filter function at the end of the chain.  But you could declare a `filter: blur(var(--blur-radius));` and then make the `--blur-radius` declarations additive.  (This of course assumes an easy way to declare the data types of custom properties for interpolation and addition.  But that's going to happen anyway, right?)

But there are other cases where you want to modify a complex value, which can't easily be deconstructed into custom properties.  For example, to insert an image layer into a `background-image` stack.  You need to add a comma token into your custom property value, and the syntax gets very fragile.

For the specific issues Brian highlighted:

> Is `!add` enough? Do we need both the add and accumulate modes described above?

I think accumulate is useful.  But it doesn't fit into the `!add` syntax.  Accumulation is a property of the animation repeat cycle, not of an individual declaration.   The entire animation would either need to accumulate or not.   And whether it accumulates or not would be separate from whether they underlying declarations were additive or not.

(I'm assuming that, for `!add` in a `@keyframes` rule set, we are always adding on to the previous value from the cascade, and not on the previous keyframe.  So it would be possible to have e.g. a 50% keyframe that was additive (so the first half of the animation is defined as a change from the base value), and then a 100% keyframe that _wasn't_ additive (final value in the animation is the same regardless of the base value).)

If you wanted to support accumulative repeats in addition to an `!add` syntax, I think the logical way to do so would be via a new `animation-*` property.  Accumulation would be something like alternating repeats or a forwards-fill mode, that is part of the overall timing and repeat structure of the animation, not part of the keyframes.

However, there would still need to be details to figure out:

- How do you define the amount of change which becomes the amount to add?  If we're being consistent with SVG/SMIL (and I think Web Animations), then the additive amount for each keyframe would be measured as the value for that keyframe relative to the `from` value.  However, SVG/SMIL only does it this way if a `from` is set explicitly, or if the relative change is set explicitly with `by`.  An animation defined with implicit `from` and explicit `to` does not accumulate in SVG/SMIL. Which doesn't translate nicely to a CSS model.  Also, `values` and `accumulate` aren't well defined together in the spec; Firefox and Chrome treat them so that the values automatically become additive, then accumulative in their difference relative to the base value, instead of relative to the starting frame.  Basically, it's a huge mess of logical inconsistencies and I'm not sure you'd want to automatically follow along to match.

- How do accumulative animations interact with reverse-direction or alternating animations?  SVG/SMIL does not have these.  The definitions in Web Animations do not appear to discuss it.

> Are there other modes we need? e.g. multiplication to produce 75% of the current opacity value. Or should that be achieved by extending calc() to be able to work with the underlying value?

Now we're getting into the complicated questions that the simple syntax can't cover.  _Which_ other combination options you want would depend on the specifics of each property type.  The more complex the property, the more different possible ways you might have for combining values.  Think of two `text-shadow` declarations: do you add them as a list, to create two shadows? Or do you add all the individual terms.  So maybe there's a `!concatenate` list option versus `!add`? But how does this compare with `!multiply` for other properties? It quickly becomes a tangle.

A simple syntax like `!add` needs a simple rule.  Just like with the [SVG/SMIL additive rules](https://www.w3.org/TR/SVG11/animate.html#AdditionAttributes), that would probably mean a very restricted set of additive data types.  As mentioned above, more complicated combinations would require CSS variables.

> Can we relax the range checking used when an !add annotation is in place so that is is possible to write opacity: -50% !add?
> (We already do this internally for SMIL and I suppose we want to do this for animation-composite anyway.)

This would be very desirable. It should be similar to `calc()` and `var()` rules for range checking, where you only clamp when you can convert it to a meaningful final value.


(This is probably it for me tonight. Sorry I didn't get a chance to review @FremyCompany's proposal. I'll be reading over the IRC minutes when I get online tomorrow.)

-- 
GitHub Notification of comment by AmeliaBR
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/1594#issuecomment-319572664 using your GitHub account

Received on Wednesday, 2 August 2017 05:37:56 UTC