Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-values-4] Validity of generic interpolation function mix() #6700

Closed
fantasai opened this issue Sep 29, 2021 · 12 comments
Closed

[css-values-4] Validity of generic interpolation function mix() #6700

fantasai opened this issue Sep 29, 2021 · 12 comments

Comments

@fantasai
Copy link
Collaborator

In #581 and #2854 we resolved to add a generic interpolation function, which takes a percentage, a start value, and an end value.

One outstanding question is: where is this notation valid?

  • It definitely needs to be valid as a top-level function that wraps the entire property's value.
  • Can it also be used as a lower-level syntax, e.g. for interpolating <length> values? What about <position> values (which have multiple components)?
@tabatkins
Copy link
Member

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
Copy link
Contributor

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) 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.

@ByteEater-pl
Copy link

ByteEater-pl commented 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:

  1. Type (i.e. treat during parsing) the new function (mix, interpolate or whatever) as returning a dimensionless number.
  2. 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).

@tabatkins
Copy link
Member

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
Copy link
Collaborator Author

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
  • some other pairing
@tabatkins
Copy link
Member

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()).

@astearns astearns moved this from Temp to Values in APAC Nov 3 2021 TPAC meeting Oct 29, 2021
@astearns astearns moved this from Values to Next week? in APAC Nov 3 2021 TPAC meeting Nov 1, 2021
@LeaVerou
Copy link
Member

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.

@fantasai
Copy link
Collaborator Author

@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
Copy link
Member

Yes, it's a shorthand, but that doesn't make it unreasonable. You have a mixing function per distinct "type" of mixable value.

But only as long as the only possible progress argument is PERCENTAGE, and we're planning to add other things than PERCENTAGE constants there.

I'm not sure what you mean by this, @fantasai?

@astearns astearns added this to Temp in December 8 meeting Dec 7, 2021
@astearns astearns moved this from Pubs and proposals to Temp2 in December 8 meeting Dec 7, 2021
@astearns astearns moved this from Temp2 to Temp3 in December 8 meeting Dec 7, 2021
@atanassov atanassov added this to Can wait until 2022 in December 15 meeting Dec 15, 2021
@atanassov atanassov moved this from Can wait until 2022 to Everything else in December 15 meeting Dec 15, 2021
@css-meeting-bot
Copy link
Member

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
@fantasai
Copy link
Collaborator Author

fantasai commented Jun 9, 2022

I'm not sure what you mean by this, @fantasai?

@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
Copy link
Member

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-values-4 Current Work
6 participants