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] Simplification of relative dimension units in Product #7456

Closed
cdoublev opened this issue Jul 5, 2022 · 0 comments
Closed

Comments

@cdoublev
Copy link
Collaborator

cdoublev commented Jul 5, 2022

Following the simplification algorithm and this comment about step 3 of parse a calculation, I do not see how 1 * 1px / 1em can be simplified to 1px / 1em, ie. Product(Product(1, 1px), Invert(1em)) can be simplified but Product(1, 1px, Invert(1em)) cannot:

What is a "run" in "every consecutive run of values"? [...]

I'm just using it as it standard English meaning, implying you take the maximal amount. In 1 * 2 * 3 * 4, it's all four values. [...] Starting with 1 * 2 * 3, this is turned into the list [1, *, 2, *, 3]. Step 3 collects those into [Product(1,2,3)].

Also, I think "if root contains only numeric values" should be followed by "expressed in their canonical unit" at step 9.4, as there is not enough information at parse time to canonicalize 1em in calc(1px / 1em), for example.

  1. If root contains only numeric values and/or Invert nodes containing numeric values, and multiplying the types of all the children [...] results in a type that matches any of the types that a math function can resolve to, return the result of multiplying all the values of the children [...], expressed in the result’s canonical unit.

Please let me know if you think the following issues/questions deserves a new issue.

How do you get a nested Invert or Negate node at steps 6.2 and 7.2?
  1. If root is a Negate node:
    1. If root’s child is a numeric value, return an equivalent numeric value, but with the value negated (0 - value).
    2. If root’s child is a Negate node, return the child’s child.
    3. Return root.
  2. If root is an Invert node:
    1. If root’s child is a number (not a percentage or dimension) return the reciprocal of the child’s value.
    2. If root’s child is an Invert node, return the child’s child.
    3. Return root.
How should min(1em) be serialized? Answer: with calc(1em) (cf. #9559)

It should parse to Min(1em) but step 5 of simplifying a calculation tree does not unwrap 1em.

  1. For each node child of root’s children: If child is a numeric value with enough information to compare magnitudes with another child of the same unit (see note in previous step), and there are other children of root that are numeric values with the same unit, combine all such children with the appropriate operator per root, and replace child with the result, removing all other child nodes involved. Return root.

  2. Return root

This is a niche case but I suggest to insert a step before step 2:

If root has only a single child, return this child.

What should be the simplified value of clamp(1px, 1em, 1rem)?

No value is returned from simplifying a calculation tree when the math function is not min() or max() and all of its calculation children are [not] numeric values with enough information to compute the operation root represents (step 4).

I suggest to add:

10. Return root.

Should parsing (and simplifying) apply bottom-up or top-down?

I am confused as to whether parsing calculations and simplifying calculation trees should granularly apply bottom-up, or top-down as a flat list of component values.

In parse a calculation:

  • step 5.1 is unclear about whether the simple block should already represent a calculation tree or if its calculation should actually be parsed at this step
  • step 5.2 is unclear about whether the math function should already represent a calculation tree or if the math function should actually be turned into a calculation tree at this step

Note: I have a working implementation parsing from bottom to top but simplifying from the top level math function.

Does step 2 of serialize a math function mean that calc(1px + infinity * 1em) should serialize to calc(infinity * 1px)?
  1. If fn represents an infinite or NaN value: [...]

The current output for a specified value in Chrome is calc(1px + infinity * 1em).

I think the calculation should be parsed and simplified to Sum(1px, Product(Infinity em)). If the infinite value is not detected in step 2 of serialize a math function, I think it should be handled at step 2 of serialize a calculation tree in order to get the same output as in Chrome.

Require the same resolved type for the calculations of min(), max(), clamp() Fixed in 66a3197

The following requirement is defined for <round()>, <mod()>, <rem()>, <atan2()>, <hypoth()>:

The argument calculations can resolve to any <number>, <dimension>, or <percentage>, but must have the same type, or else the function is invalid

But it is not defined for min(), max(), clamp().

The related paragraphs in 10.9 Type Checking can be merged:

Math functions themselves have types, according to their contained calculations:

  • [...]
  • The type of a min(), max(), or clamp() expression is the result of adding the types of its comma-separated calculations.
  • [...]
  • The type of a hypot(), round(), mod(), or rem() expression is the result of adding the types of its comma-separated calculations.
@cdoublev cdoublev changed the title [css-values-4] Do not simplify a calc Product node containing a non-canonical dimension unit [css-values-4] Multiply a number and a non-canonical dimension unit Jul 5, 2022
@cdoublev cdoublev changed the title [css-values-4] Multiply a number and a non-canonical dimension unit [css-values-4] Simplification of relative dimension units in Product Jul 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant