You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-values-4] Validity of generic interpolation function mix() #6700
It can't be used as a lower-level syntax, unfortunately.
We have to be able to tell, at parse-time, what the type of the function is, and do so without clever grammar manipulation (because browsers don't have powerful-enough grammar handling tools right now, and have no plans to add such). That is, any attempt to define their parse-time validity as something like "sub it and see if it works" is a no-go. I tried that with var() fallback values and had to back it out, because when you had two or more var() functions they can interact in complex ways and you have exponential checking possibilities.
The existing mixing functions are fine in this regard - math functions define precisely how to determine their type, cross-fade() is an <image>, color-mix() is a <color>.
This is also important because we have to know how to interpolate the values; a bare "red" as one of the values might be a color keyword and want to be interpolated "as <color>", but we can't know that for certain without the clever grammar manipulation (putting it in, parsing the property, and seeing what component it gets assigned to).
Whole-property values are fine, because their interpolation type is just "the property it's being used in".
So, any low-level interpolation function must be type-specific and clearly advertise its type at parse-time in some manner.
mix() is just top-level, but accepts arbitrary values that can be used in that property, and interpolates according to the property.
For example, aspect-ratio: mix(50%, 1, 9) is 3.
interp() or something from [css-values] Add easing function interpolation to calc #6697 is lower-level, but only interpolates calculation values, and interpolates according to the type of the calculation.
For example, aspect-ratio: calc(interp(50%, 1, 9)) is 5.
With both of them, I guess most usecases will be covered.
Two alternatives which would allow it to be used as a lower-level syntax despite browser implementors' opposition to requiring type inference:
Type (i.e. treat during parsing) the new function (mix, interpolate or whatever) as returning a dimensionless number.
Add an (optional, with dimensionless by default?) argument indicating the type (e.g. length, taken from CSS grammar). Percentages are always also valid (so e.g. no need to specify (or even allow) length-percentage).
I prefer (2) (it even subsumes (1) if the type is optional), but probably a very common case would be to express a dimensionless number and multiply it by a dimensioned constant (likely 1).
If we have a separate interpolation function for top-level values vs. component values like 5em, I think their syntax should be as identical as possible and they just differ in name.
And also, the names should be coordinated, e.g. share the ''-mix'' suffix or whatever. So mabye
''mix()'' vs ''calc-mix()'', or
''value-mix()'' vs ''mix()'' (since calc mix is likely the more common), or
Yeah agreed; specifically, the numeric one should look as close to color-mix() as possible, as the most clear parallel.
I'm fine with the property-mixer being named mix(); it's not obvious to me, at least, which will end up most popular, and the typed mixers already have a tradition (n==2, but still) of more specific names (cross-fade(), color-mix()).
What are the use cases for calc-mix() or whatever it ends up being called? Is it just a shorthand for calc(a * p + b * (1 - p))? Or would it also accept keywords like auto, min-height etc?
I’m a little concerned that we're adding multiple syntaxes authors need to be able to decide between, doing very similar things, for parsing reasons that are really difficult to explain to authors.
@LeaVerou calc-mix() definitely should not be introducing new functionality to calc() so yes, it's a shorthand. But only as long as the only possible progress argument is PERCENTAGE, and we're planning to add other things than PERCENTAGE constants there.
The CSS Working Group just discussed [css-values-4] Validity of generic interpolation function mix(), and agreed to the following:
RESOLVED: The mix interpolation function will only be used for top-level values with various discussed caveats. mix is the name of the top level interpolation
The full IRC log of that discussion
<dael> Topic: [css-values-4] Validity of generic interpolation function mix()
<dael> github: https://github.com//issues/6700
<dael> TabAtkins: Making sure we agree what generic interpolation does and if it's valid
<dael> astearns: Only concern is last comment asked for fantasai to clarify
<dael> TabAtkins: True. But not relivent for this, I think.
<dael> TabAtkins: We have a couple of mixing functions lick color-mix and calc. These functions have a type. Color-mix is a color, valid whereever a color is. But generic interpolation function, currently called mix, I don't believe can be same
<dael> TabAtkins: It can interp things without describable types. Interp of a box shadow is only valid in box shadow.
<dael> TabAtkins: Prop is mix is only allowed as top-level value of a property. That's all it would be produced as by UA, but if authors use it they could not combine with other things. Can't mix 2 box shadows and then add inset.
<smfr> q+
<dael> TabAtkins: I believe that's all this is about, verifying that's what we want for the grammar of this function
<dael> TabAtkins: If no one disagrees we can resolve
<astearns> ack smfr
<dael> smfr: Questions- if you have prop with comma sep values like backgrounds, can you use mix in the list or is the whole list a mix?
<dael> TabAtkins: Great question. Hmm.
<dael> TabAtkins: I think still the entire thing. Even in lists of comma sep we can have distinct syntaxes at a position like bg where only color in the last. We couldn't interp a mix with a color unless it's final. So would have to be the entire thing
<dael> smfr: High level, how does this interact with animations? Can I use it in keyframes?
<dael> TabAtkins: SHould be usable anywhere that accepts a value. Value is generatable by an animation so it should be a valid value. You can interp to this. Things you can do by hand should allow explicitly.
<dael> smfr: keyframe? only animatable properties?
<dael> TabAtkins: Yes, if prop wasn't animatable then mix wouldn't have a meaning. Great question and not in spec. I suspect should be properties that are not animatable mix isinvaid at parse time.
<dael> smfr: If you can spec in keyframes implies mix can nest
<dael> TabAtkins: because you can mix between and mixed value and something?
<dael> smfr: Yeah
<dael> TabAtkins: True. Good clarification. mix should be able to be an entire argument of the mix. You should be able to mix mixes
<dael> smfr: Shorthands vs longhands when mix is the enitre value?
<dael> TabAtkins: We had an answer. I believe it needs to be similar to variable in shorthands, but don't recall exactly. Whatever it was, we can't rely syntaxtically that something is a shorthand so whatever we define has to work well for shorthands.
<dael> TabAtkins: Mix should be allowed in a shorthand. Exact interp I can't answer but should be as reasonable as can make it
<dael> smfr: SOunds good
<dael> astearns: Looking for resolution to define mix as only top level
<dael> astearns: Issue also talks about adding another lower level value. punt that for now?
<dael> TabAtkins: Yeah, it's separate
<dael> astearns: But if we expect lower question is which gets the shorter name
<dael> TabAtkins: My arguement is the existing lower-level have longer names like color-mix. Completely usuable anywhere should get the shortest name. no way to be generic low-level because we need to know type to parse. Interp at the value level will be type specific. mix should have short names and others longer and more specific
<dael> astearns: Other questions or ideas?
<dael> astearns: Prop: The mix interpolation function will only be used for top-level values with various discussed caveats
<dael> TabAtkins: Sound also resolve on name
<dael> astearns: And mix is the name of the top level interpolation
<dael> astearns: Objections
<dael> RESOLVED: The mix interpolation function will only be used for top-level values with various discussed caveats. mix is the name of the top level interpolation
<dael> astearns: Since this issue discusses lower level, is that captured elsewhere or should we open another issue
<dael> TabAtkins: One talked about is numeric and that does have an issue for it
<dael> astearns: I'll see if I can find it and link it
@tabatkins We're planning to add things that don't parse as a percentage, they output a percentage. So the syntax space for the percentage of the mix() function is going to get way more complicated with things that aren't going to be allowed inside calc().
I'm still not sure what you mean - it sounds like you're saying that you want to allow functions that return a percentage, but that would be compatible with having the argument be <percentage>, so I'm not sure what the issue is. Can you provide an example?
Activity
tabatkins commentedon Sep 30, 2021
It can't be used as a lower-level syntax, unfortunately.
We have to be able to tell, at parse-time, what the type of the function is, and do so without clever grammar manipulation (because browsers don't have powerful-enough grammar handling tools right now, and have no plans to add such). That is, any attempt to define their parse-time validity as something like "sub it and see if it works" is a no-go. I tried that with
var()fallback values and had to back it out, because when you had two or more var() functions they can interact in complex ways and you have exponential checking possibilities.The existing mixing functions are fine in this regard - math functions define precisely how to determine their type, cross-fade() is an
<image>, color-mix() is a<color>.This is also important because we have to know how to interpolate the values; a bare "red" as one of the values might be a color keyword and want to be interpolated "as
<color>", but we can't know that for certain without the clever grammar manipulation (putting it in, parsing the property, and seeing what component it gets assigned to).Whole-property values are fine, because their interpolation type is just "the property it's being used in".
So, any low-level interpolation function must be type-specific and clearly advertise its type at parse-time in some manner.
Loirooriol commentedon Oct 1, 2021
So if I get it right,
mix()is just top-level, but accepts arbitrary values that can be used in that property, and interpolates according to the property.For example,
aspect-ratio: mix(50%, 1, 9)is3.interp()or something from [css-values] Add easing function interpolation to calc #6697 is lower-level, but only interpolates calculation values, and interpolates according to the type of the calculation.For example,
aspect-ratio: calc(interp(50%, 1, 9))is5.With both of them, I guess most usecases will be covered.
ByteEater-pl commentedon Oct 2, 2021
Two alternatives which would allow it to be used as a lower-level syntax despite browser implementors' opposition to requiring type inference:
mix,interpolateor whatever) as returning a dimensionless number.length, taken from CSS grammar). Percentages are always also valid (so e.g. no need to specify (or even allow)length-percentage).I prefer (2) (it even subsumes (1) if the type is optional), but probably a very common case would be to express a dimensionless number and multiply it by a dimensioned constant (likely 1).
tabatkins commentedon Oct 2, 2021
Treating is as a number for grammar purposes wouldn't be useful; it would just be invalid in any place you wanted to use it that wasn't a number.
We could potentially add a type explicitly; the problem is that it only actually gets us a few more types of things, really.
fantasai commentedon Oct 15, 2021
If we have a separate interpolation function for top-level values vs. component values like 5em, I think their syntax should be as identical as possible and they just differ in name.
And also, the names should be coordinated, e.g. share the ''-mix'' suffix or whatever. So mabye
tabatkins commentedon Oct 15, 2021
Yeah agreed; specifically, the numeric one should look as close to color-mix() as possible, as the most clear parallel.
I'm fine with the property-mixer being named mix(); it's not obvious to me, at least, which will end up most popular, and the typed mixers already have a tradition (n==2, but still) of more specific names (cross-fade(), color-mix()).
LeaVerou commentedon Nov 16, 2021
What are the use cases for
calc-mix()or whatever it ends up being called? Is it just a shorthand forcalc(a * p + b * (1 - p))? Or would it also accept keywords likeauto,min-heightetc?I’m a little concerned that we're adding multiple syntaxes authors need to be able to decide between, doing very similar things, for parsing reasons that are really difficult to explain to authors.
fantasai commentedon Nov 30, 2021
@LeaVerou calc-mix() definitely should not be introducing new functionality to calc() so yes, it's a shorthand. But only as long as the only possible progress argument is PERCENTAGE, and we're planning to add other things than PERCENTAGE constants there.
tabatkins commentedon Nov 30, 2021
Yes, it's a shorthand, but that doesn't make it unreasonable. You have a mixing function per distinct "type" of mixable value.
I'm not sure what you mean by this, @fantasai?
css-meeting-bot commentedon Jan 6, 2022
The CSS Working Group just discussed
[css-values-4] Validity of generic interpolation function mix(), and agreed to the following:RESOLVED: The mix interpolation function will only be used for top-level values with various discussed caveats. mix is the name of the top level interpolationThe full IRC log of that discussion
<dael> Topic: [css-values-4] Validity of generic interpolation function mix()<dael> github: https://github.com//issues/6700
<dael> TabAtkins: Making sure we agree what generic interpolation does and if it's valid
<dael> astearns: Only concern is last comment asked for fantasai to clarify
<dael> TabAtkins: True. But not relivent for this, I think.
<dael> TabAtkins: We have a couple of mixing functions lick color-mix and calc. These functions have a type. Color-mix is a color, valid whereever a color is. But generic interpolation function, currently called mix, I don't believe can be same
<dael> TabAtkins: It can interp things without describable types. Interp of a box shadow is only valid in box shadow.
<dael> TabAtkins: Prop is mix is only allowed as top-level value of a property. That's all it would be produced as by UA, but if authors use it they could not combine with other things. Can't mix 2 box shadows and then add inset.
<smfr> q+
<dael> TabAtkins: I believe that's all this is about, verifying that's what we want for the grammar of this function
<dael> TabAtkins: If no one disagrees we can resolve
<astearns> ack smfr
<dael> smfr: Questions- if you have prop with comma sep values like backgrounds, can you use mix in the list or is the whole list a mix?
<dael> TabAtkins: Great question. Hmm.
<dael> TabAtkins: I think still the entire thing. Even in lists of comma sep we can have distinct syntaxes at a position like bg where only color in the last. We couldn't interp a mix with a color unless it's final. So would have to be the entire thing
<dael> smfr: High level, how does this interact with animations? Can I use it in keyframes?
<dael> TabAtkins: SHould be usable anywhere that accepts a value. Value is generatable by an animation so it should be a valid value. You can interp to this. Things you can do by hand should allow explicitly.
<dael> smfr: keyframe? only animatable properties?
<dael> TabAtkins: Yes, if prop wasn't animatable then mix wouldn't have a meaning. Great question and not in spec. I suspect should be properties that are not animatable mix isinvaid at parse time.
<dael> smfr: If you can spec in keyframes implies mix can nest
<dael> TabAtkins: because you can mix between and mixed value and something?
<dael> smfr: Yeah
<dael> TabAtkins: True. Good clarification. mix should be able to be an entire argument of the mix. You should be able to mix mixes
<dael> smfr: Shorthands vs longhands when mix is the enitre value?
<dael> TabAtkins: We had an answer. I believe it needs to be similar to variable in shorthands, but don't recall exactly. Whatever it was, we can't rely syntaxtically that something is a shorthand so whatever we define has to work well for shorthands.
<dael> TabAtkins: Mix should be allowed in a shorthand. Exact interp I can't answer but should be as reasonable as can make it
<dael> smfr: SOunds good
<dael> astearns: Looking for resolution to define mix as only top level
<dael> astearns: Issue also talks about adding another lower level value. punt that for now?
<dael> TabAtkins: Yeah, it's separate
<dael> astearns: But if we expect lower question is which gets the shorter name
<dael> TabAtkins: My arguement is the existing lower-level have longer names like color-mix. Completely usuable anywhere should get the shortest name. no way to be generic low-level because we need to know type to parse. Interp at the value level will be type specific. mix should have short names and others longer and more specific
<dael> astearns: Other questions or ideas?
<dael> astearns: Prop: The mix interpolation function will only be used for top-level values with various discussed caveats
<dael> TabAtkins: Sound also resolve on name
<dael> astearns: And mix is the name of the top level interpolation
<dael> astearns: Objections
<dael> RESOLVED: The mix interpolation function will only be used for top-level values with various discussed caveats. mix is the name of the top level interpolation
<dael> astearns: Since this issue discusses lower level, is that captured elsewhere or should we open another issue
<dael> TabAtkins: One talked about is numeric and that does have an issue for it
<dael> astearns: I'll see if I can find it and link it
fantasai commentedon Jun 9, 2022
@tabatkins We're planning to add things that don't parse as a percentage, they output a percentage. So the syntax space for the percentage of the mix() function is going to get way more complicated with things that aren't going to be allowed inside calc().
tabatkins commentedon Jun 17, 2022
I'm still not sure what you mean - it sounds like you're saying that you want to allow functions that return a percentage, but that would be compatible with having the argument be
<percentage>, so I'm not sure what the issue is. Can you provide an example?[css-values-4] mix() is only valid as the sole value #6700