Skip to content

[css-easing-2] How to generate a computed value for linear-spline() #7415

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

Closed
jakearchibald opened this issue Jun 24, 2022 · 6 comments
Closed
Labels
css-easing-2 Current Work

Comments

@jakearchibald
Copy link
Contributor

My initial thought was to serialize it the same as CSS gradients, as being similar to CSS gradients was one of the attractive parts of linear-spline(). However, @dshin-moz has pointed out how weird the computed value for gradients is.

Input:
linear-gradient(to right, <<color>>, <<color>> 50%, <<color>>)
Computed:
linear-gradient(to right, <<color>>, <<color>> 50%, <<color>>)

(I'm using <<color>> instead of values here, as Safari serializes them differently, and it's irrelevant to this issue)

The position value only appears in the output if it appeared in the declaration.

Input:
linear-gradient(to right, <<color>> 80%, <<color>> 10%)
Computed:
linear-gradient(to right, <<color>> 80%, <<color>> 10%)

Position values are not clamped to the position of their previous value.

Input:
linear-gradient(to right, <<color>>, <<color>> 50% 80%)
Computed:
linear-gradient(to right, <<color>>, <<color>> 50%, <<color>> 80%)

The second stop position is expanded into two entries.

So, what should we do for linear-spline()?

Option 1: Copy linear-gradient

Follow all of the rules above, even though they're a bit weird.

Option 2: Output fully computed value

  • Unfold 0 50% 80% into two entries: 0 50%, 0 80%
  • Include calculated positions, so 0, 0.5, 1 becomes 0 0%, 0.5 50%, 1 100%
  • Include corrections made to positions, so 0 50%, 1 20% becomes 0 50%, 1 50%

Option 3: Output closer to authored format

  • If a second stop is provided (eg 0 50% 80%) it's retained in the output
  • Positions are only included if they were included in the declaration, so 0, 0.5, 1 remains 0, 0.5, 1
  • Positions are not corrected, so 0 50%, 1 20% remains 0 50%, 1 20%.

My preference is option 2, as it allows developers to see the validation and calculation that took place.

@dshin-moz
Copy link

dshin-moz commented Jun 24, 2022

Additional context - multi position syntax for linear-gradient was added later, and the current behaviour was chosen for back compat (Issue 2714)
I do prefer option 2, but it could definitely trip people up translating their mental model.

@emilio emilio added the css-easing-2 Current Work label Jun 24, 2022
@tabatkins
Copy link
Member

(Small but important nit: this is not about the computed value, it's about the serialization of the computed value. The computed value itself is an internal spec concept that can be turned into a string or an object (in principle, at least, if the Typed OM defines rules for it), and should be defined for easy of use in specs and/or ease of mapping to likely internal implementation concepts.)

Gradients are weird, but not for no reason. They stick with the general CSS policy that everything that can be (reasonably) implicitly omitted in parsing, is omitted when serializing the computed value. Unfortunately, they also have to deal with the fact that %s rely on layout information to resolve, so you cannot (in general) know at computed-value time whether stops are out of order, or how to expand omitted positions. So, fixup and calculation isn't done at all at computed-value time and the stops are kept as-is.

(This isn't an absolute policy - we don't combine same-color stops into a two-position stop, for example, because that requires extra logic to re-coalesce the steps and we felt it's probably more useful for authors to have a consistent model than one that sometimes had double positions and sometimes didn't. There's thus some wiggle room.)

None of this is the case for linear-spline() - %s are the only unit, so you can immediately fill in omitted positions and do fixup. I recommend doing so, then (again, leaning on the principle that a consistent structure for the stops is better than an inconsistent one).

So my proposal, in short:

  • Unfold multi-positions into single-position stops
  • Do out-of-order fixup, then omitted-position fixup, and serialize the positions with each stop. (Note the fixup order - it's important and will match gradients.)

@jakearchibald
Copy link
Contributor Author

That sounds like option 2. That order of operations you describe is already in the PR, unless I fucked it up.

Thank you for the detailed description! All sorts of stuff I wasn't fully aware of in there. Cheers!

(It also simplifies the algorithm, as I don't need to keep a separate structure around just for serialisation)

@tabatkins
Copy link
Member

Yes, option 2, just with the order of fixup swapped (assuming your bullet points were suggesting that ordering in particular).

@jakearchibald
Copy link
Contributor Author

Ah, nah, I wasn't thinking of a particular order in this issue. I think the PR has the right order, but I will double check.

@jakearchibald
Copy link
Contributor Author

Settled on option 2 in #7414

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jul 8, 2022
…function calculation. r=emilio

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
aosmond pushed a commit to aosmond/gecko that referenced this issue Jul 8, 2022
…function calculation. r=emilio

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Jul 10, 2022
…function calculation. r=emilio

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Jul 11, 2022
…function calculation. r=emilio

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
moz-wptsync-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 11, 2022
…ulation.

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1766041
gecko-commit: 069ca54ccaa2e3e400409b4369882cd72e466e26
gecko-reviewers: emilio
moz-wptsync-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jul 11, 2022
…ulation.

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1766041
gecko-commit: 069ca54ccaa2e3e400409b4369882cd72e466e26
gecko-reviewers: emilio
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 25, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 25, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 25, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 25, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 25, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Sep 28, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Loirooriol pushed a commit to Loirooriol/servo that referenced this issue Oct 2, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
github-merge-queue bot pushed a commit to servo/servo that referenced this issue Oct 2, 2023
…lation

This was made economical by having Rust's computed `easing::TimingFunction` use
a fully resolved function for `linear(...)` easing, as per draft resolution from
w3c/csswg-drafts#7415

Differential Revision: https://phabricator.services.mozilla.com/D151295
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-easing-2 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants