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] How to interpolate <ratio>? #4953

Closed
tabatkins opened this issue Apr 15, 2020 · 18 comments
Closed

[css-values-4] How to interpolate <ratio>? #4953

tabatkins opened this issue Apr 15, 2020 · 18 comments

Comments

@tabatkins
Copy link
Member

I'm moving the definition of <ratio> over to V&U right now, per #4908, but I'm stuck on how ratios should interpolate (which is simply not defined right now in Sizing, the only place where a ratio is potentially interpolable).

Two obvious answers:

  1. Keep around the original pair of values, and interpolate numerator and denominator separately.
  2. Resolve the ratio into a single number, and interpolate that value. (Aka turn it into X / 1 form.)

Here's a test showing off the behaviors.

I think that, in general, I like "interpolate numerator and denominator separately" better. In particular, if the two ratios are on the same scale, the behavior ends up being identical to just interpolating the width and height independently.

Note, tho, the fourth box on that page - it's still interpolating between the same two ratios, but one ratio is expressed as 5/1, and the other is 300/200. This gives a ridiculous result, that just happens to land on the exact right sizes at the beginning and end. This means that option 1 is scale-dependent, which is probably not a good thing to have!

Further complications: if we go with "interpolate the divided result", that implies that the computed value has to be the divided result, I think? Which means that if you write 3/2, we'll lose that information, and can only serialize it as 1.5/1, which seems bad.

So I'm not sure. What does the group think? Option 1, with a warning that people probably want to ensure their numbers are on similar scales? (They usually will be.) Or Option 2, and bite the bullet on serialization?

@tabatkins tabatkins added the css-values-4 Current Work label Apr 15, 2020
@AmeliaBR
Copy link
Contributor

if we go with "interpolate the divided result", that implies that the computed value has to be the divided result, I think?

I don't see why. For transforms, we “upgrade” values as needed for interpolation, in a way that's separate from how computed values work.

So, without that objection, I'd definitely argue for scaling to a denominator over 1 before interpolating numerators. Or alternatively, scaling up to a lowest common multiple denominator, to avoid precision issues from decimals. E.g., 5/1→300/200 would be interpolated as 1000/200→300/200. But that should give the same results, minus precision issues, as 5/1→1.5/1

@Loirooriol
Copy link
Contributor

Here's a test showing off the behaviors.

You forgot to animate the width of the 4th case. Here is the fixed showcase, also highlighting the start and end sizes: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/7976

This means that option 1 is scale-dependent

Specifically, if I got it right, linearly interpolating aspect-ratio from a/b to c/d with option 1 and width from a * k0 to c * k1 will only result in a linear interpolation for height if k0 = k1.

However, it's not clear to me that we should try to get that behavior. If some author wants to get the same behavior as if the width and height were interpolated independently, maybe they should just convert the initial and final widths into heights using the initial and final ratios, and actually interpolate height instead of aspect-ratio.

@tabatkins
Copy link
Member Author

I don't find the linear interpolation necessary, but looking at the two examples, I do find it better-looking, at least when they're on the same scale.

But the scale-dependence really bothers me on a spec level (it shouldn't matter!), and looks terrible in practice when the scales differ by a lot.

I don't see why. For transforms, we “upgrade” values as needed for interpolation, in a way that's separate from how computed values work.

Ah you're right. That resolves my issue, then. Let's just specify behavior 2 (interpolate over the division result), then.

@tabatkins tabatkins added Closed Accepted by Editor Discretion Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. Needs Testcase (WPT) labels Oct 8, 2020
@dbaron
Copy link
Member

dbaron commented Oct 19, 2020

It seems like it might be better to interpolate the logarithm of the division result, or perhaps some other function of the division result that would produce symmetric results between animation from 1/2 to 1/10 and animation from 2/1 to 10/1, which seems like it would be good for the aspect-ratio property.

@fantasai fantasai reopened this Oct 19, 2020
@tabatkins
Copy link
Member Author

@dbaron That is an excellent point: using division lets us avoid a scale-dependence (so going from 2/1 to 10/1 is the same as going from 20/10 to 100/10), but it still introduces an orientation dependence; tall and wide versions of the same ratios interpolate differently.

Using the logarithm of the division, then, seems to make a lot of sense - it'll interpolate your examples by going from (wlog, using log2) 1 to 3.32 for the first, and from -1 to -3.32 for the second, exactly symmetric.

It also means that going from 1/2 to 2/1 will end up with a square 1/1 ratio in the middle of the transition, which I think is what authors would expect.

So if nobody objects, I'll change to using the logarithm of the division result.

@Loirooriol
Copy link
Contributor

So, the proposal is that the interpolation between two ratios r1 and r2 at distance p should be

exp((1 - p) * log(r1) + p * log(r2))

? Or equivalently,

(r1 ** (1 - p)) * (r2 ** p)

Note that 0 / 1 has a -infinity logarithm, so interpolating between 0 / 1 and 1 / 1 won't be fluid. But that was already the case for 1 / 0 and 1 / 1.

Also note that doing it linearly has the advantage that you can fix height: h and interpolate aspect-ratiofrom r1 to r2, then width changes linearly from h * r1 to h * r2. If ratios are interpolated logarithmically, we lose this property, but we didn't have it either when fixing width: w instead.

Example table:

Fixed style Interpolation p = 0 p = .5 p = 1
height: 5px 2/1 -> 18/1
linearly
aspect-ratio: 2/1
width: 10px
aspect-ratio: 10/1
width: 50px
aspect-ratio: 18/1
width: 90px
width: 180px 2/1 -> 18/1
linearly
aspect-ratio: 2/1
height: 90px
aspect-ratio: 10/1
height: 18px
aspect-ratio: 18/1
height: 10px
height: 5px 2/1 -> 18/1
logarithmically
aspect-ratio: 2/1
width: 10px
aspect-ratio: 6/1
width: 30px
aspect-ratio: 18/1
width: 90px
width: 180px 2/1 -> 18/1
logarithmically
aspect-ratio: 2/1
height: 90px
aspect-ratio: 6/1
height: 30px
aspect-ratio: 18/1
height: 10px

So this would make it symmetric, seems good to me.

@dbaron
Copy link
Member

dbaron commented Oct 20, 2020

One other possibility that I think might work better that logarithms and still have the desirable properties of avoiding scale-dependence and orientation-dependence is to instead use the function

I(r) = r - 1, for r ≥ 1
I(r) = 1 - (1/r), for r < 1

since I think at least for aspect-ratio it might produce smoother size animations, at least when it's the larger size in the ratio that's moving and the smaller size that's fixed.

Note that this is easily invertible:
I'(t) = t + 1, for t ≥ 0
I'(t) = 1/(1-t), for t < 0

@dbaron
Copy link
Member

dbaron commented Oct 20, 2020

Figuring out which of these two is better may require constructing demos. Though it also might make the rules for <ratio> animation particularly tied to what we want for aspect-ratio, which may or may not be ideal for any future uses of <ratio> in property values.

@tabatkins
Copy link
Member Author

Note that 0 / 1 has a -infinity logarithm, so interpolating between 0 / 1 and 1 / 1 won't be fluid. But that was already the case for 1 / 0 and 1 / 1.

Yeah, that's the point, it now acts identically whether you're going from "square" to "infinitely tall" as to "infinitely wide". That's nice!

Figuring out which of these two is better may require constructing demos.

I'll write a few.

@Loirooriol
Copy link
Contributor

One other possibility that I think might work better that logarithms

For ratios ≥ 1, this reduces to linear interpolation. So it still has the same problem: if you fix height and animate aspect-ratio, width will change linearly. But if you fix width and animate aspect-ratio, height will change hyperbolically. So its not symmetric in this sense. I think I prefer logarithmic interpolation.

@tabatkins
Copy link
Member Author

Yeah, considering that I think all of the solutions look worse than "interpolate the numerator and denominator separately", I don't think fine details in the interpolation will matter too much. But logarithmic scaling has really appealing mathematical properties.

@dbaron
Copy link
Member

dbaron commented Oct 21, 2020

For ratios ≥ 1, this reduces to linear interpolation. So it still has the same problem: if you fix height and animate aspect-ratio, width will change linearly. But if you fix width and animate aspect-ratio, height will change hyperbolically. So its not symmetric in this sense. I think I prefer logarithmic interpolation.

But there is a symmetry: the way it behaves when fixing height when the ratio is > 1 is the way it behaves when fixing width when the ratio is < 1, and vice-versa.

@tabatkins
Copy link
Member Author

Here, I've rendered some demos: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/8633

Logarithmic and dbaron's "inverted linear" are pretty close overall; I don't see a significant distinction between them.

As such, I'm still leaning slightly towards logarithmic, as I think it has the better overall mathematical behavior.

@tabatkins
Copy link
Member Author

Actually if you try out more extreme ratios, like 1:1 transitioning to 10:1, I like log a lot better; linear and inverted-linear both spend most of their time in the high ratios, which are hard to tell apart, while log appears to have more even progress.

Doing 1:1 transitioning to 1:10 (where "inverted linear" makes the height move linearly) it's more of a tossup; they're both clearly better than linear, but I'm not sure which I prefer between log and inverted-linear.

So yeah, still supporting log, I think.

@Loirooriol
Copy link
Contributor

Added option to fix height: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/8634

When fixing height and going from 1:1 to 1:10, I don't like dbaron's, it behaves like linear when fixing width. So I also lean towards log.

@fantasai fantasai removed Closed Accepted by Editor Discretion Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. labels Oct 28, 2020
@fantasai
Copy link
Collaborator

Side note on process: "Editor Discretion" imho should only be used when

  • the solution isn't obvious (that's Bugfix) or editorial (that's Editorial)
  • the impact of the solution is minor and localized (no cross-module impact or consistency concern, unlikely to affect implementation architecture)
  • no syntax/API is affected
  • There is consensus among the people in the discussion, and no WG member not involved is likely to care.

Otherwise, it should be Agenda+ and closed by CSSWG resolution in order to get consensus among all the people likely to care.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-values-4] How to interpolate <ratio>?, and agreed to the following:

  • RESOLVED: Interpolate ratios using log
The full IRC log of that discussion <dael> Topic: [css-values-4] How to interpolate <ratio>?
<dael> github: https://github.com//issues/4953
<dael> TabAtkins: Currently the value and units spec defines that ratios are interp by devide and interpolate the number. Bad. It's simple but has bad properties. Grossly asymmetrical between tall and wide. tall has 1-0 range and wide is 1-infinity
<dael> TabAtkins: If going from 1-1 to 10-1 if it goes tall it spends most of it's time being close to square. Takes a long time to go 1 -> .1 But if you're going wide you're spending most of the time close to 10
<dael> TabAtkins: A much better way to preserve the symmetry is to take the log of the division results and interpolate that and exponent to get back to the ratio. Gives you idential behavior. Makes sure if you're going 2-1 that halfway is suqare
<dael> TabAtkins: Suggestion for dbaron has other asymmetries. If you want details it's in the issue and oriol has examples of where the assymetry comes in
<fantasai> oriol made demos at http://software.hixie.ch/utilities/js/live-dom-viewer/saved/8634
<dael> TabAtkins: Would like to transition ratios using log of result. I think this is fine for future uses. Produces pleasing visual transition. Symmetry should be good for all cases
<florian> sounds good to me
<dael> TabAtkins: Prep to resolve to use the log. Other thoughts we can go back to the issue
<dael> astearns: Additional comments?
<dael> astearns: Prop: Interpolate ratios using log
<dael> RESOLVED: Interpolate ratios using log

@Loirooriol
Copy link
Contributor

@tabatkins I think the formula needs to special-case positive/0, 0/positive and 0/0 at interpolation boundaries. For example, the interpolation between 0/1 and 1/1 at distance 1 should be 1/1 according to https://drafts.csswg.org/css-values/#interpolation, but the formula produces 10^(log(0)*0 + log(1)*1) = 10^(-∞*0 + 0*1) = NaN = 0/0.

Also, it may be useful to note that the formula can be simplified to ratio1^(1-p) * ratio2^p, and in the halfway example this is the geometric mean.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 11, 2020
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug:1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 21, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug:1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 21, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug:1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 22, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug:1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 22, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 22, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}
blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this issue Jan 22, 2021
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Feb 2, 2021
…port., a=testonly

Automatic update from web-platform-tests
Implement aspect-ratio interpolation support.

Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}

--

wpt-commits: d4719bcb025560fe81b4b8dd737608cbe0d77030
wpt-pr: 26856
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Feb 3, 2021
…port., a=testonly

Automatic update from web-platform-tests
Implement aspect-ratio interpolation support.

Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <keverschromium.org>
Reviewed-by: Xida Chen <xidachenchromium.org>
Commit-Queue: Robert Flack <flackrchromium.org>
Cr-Commit-Position: refs/heads/master{#846135}

--

wpt-commits: d4719bcb025560fe81b4b8dd737608cbe0d77030
wpt-pr: 26856

UltraBlame original commit: 375a9dea6eb7eddf08419c25b71de2d3aab97bdd
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Feb 3, 2021
…port., a=testonly

Automatic update from web-platform-tests
Implement aspect-ratio interpolation support.

Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <keverschromium.org>
Reviewed-by: Xida Chen <xidachenchromium.org>
Commit-Queue: Robert Flack <flackrchromium.org>
Cr-Commit-Position: refs/heads/master{#846135}

--

wpt-commits: d4719bcb025560fe81b4b8dd737608cbe0d77030
wpt-pr: 26856

UltraBlame original commit: 375a9dea6eb7eddf08419c25b71de2d3aab97bdd
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Feb 3, 2021
…port., a=testonly

Automatic update from web-platform-tests
Implement aspect-ratio interpolation support.

Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <keverschromium.org>
Reviewed-by: Xida Chen <xidachenchromium.org>
Commit-Queue: Robert Flack <flackrchromium.org>
Cr-Commit-Position: refs/heads/master{#846135}

--

wpt-commits: d4719bcb025560fe81b4b8dd737608cbe0d77030
wpt-pr: 26856

UltraBlame original commit: 375a9dea6eb7eddf08419c25b71de2d3aab97bdd
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Feb 4, 2021
…port., a=testonly

Automatic update from web-platform-tests
Implement aspect-ratio interpolation support.

Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}

--

wpt-commits: d4719bcb025560fe81b4b8dd737608cbe0d77030
wpt-pr: 26856
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this issue Oct 14, 2022
Based on the discussion in w3c/csswg-drafts#4953
aspect ratios should be interpolated by the log of their value preserving
the same visual speed whether they are wide or narrow.

This patch adds a new interpolation type for aspect ratios and uses it
for interpolating the CSS aspect-ratio property.

Bug: 1156160
Change-Id: I6cbff0abef54290de559a7625e24e3c4e1f1e0e9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586234
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Reviewed-by: Xida Chen <xidachen@chromium.org>
Commit-Queue: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#846135}
GitOrigin-RevId: 4d02791fc5a96532045066d58ea958aed1d5b524
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants