Bug 255280 - CSS bug: Support division/multiplication of mixed units
Summary: CSS bug: Support division/multiplication of mixed units
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-04-11 05:39 PDT by Brandon McConnell
Modified: 2023-10-04 11:39 PDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brandon McConnell 2023-04-11 05:39:57 PDT
# Summary:
When dividing a length by another length, the CSS parser in the browser should return a number as specified in the `css-values-4` spec. However, this functionality is not yet implemented and instead throws an error or produces an unexpected result.

# Steps to Reproduce:
1. Create a CSS file with the following rule:
```css
div {
  width: 200px / 20px;
}
```
2. Link the CSS file to an HTML file with a `div` element.
3. Open the HTML file in the browser.

### Expected Results:
The `div` element should have a `width` of `10` since `200px / 20px` equals `10`.

### Actual Results:
The `div` element either does not have a `width` set or has an unexpected value such as `NaN` or an error message is thrown.

# Environment:
- Browser: [insert browser name and version]
- Operating System: [insert operating system name and version]

# Additional Information:
- The `css-values-4` spec specifies that multiplication and division are no longer restricted to specific argument types and can produce complex intermediate results. This change in functionality should be implemented in the browser's CSS parser.
- The lack of this functionality can lead to unexpected behavior in web pages and hinder the ability of developers to create responsive designs.
- This issue affects all web pages that use division of lengths in CSS rules.
- This issue can be worked around by manually calculating the result of the division and using that value instead of the division operation. However, this is not ideal and can lead to less readable and maintainable code.

# Related resources and discussions
- Discussion: https://github.com/w3c/csswg-drafts/issues/7448
- Specification: https://drafts.csswg.org/css-values/#calc-type-checking
  > NOTE: In previous versions of this specification, multiplication and division were limited in what arguments they could take, to avoid producing more complex intermediate results (such as 1px * 1em, which is <length>²) and to make division-by-zero detectable at parse time. This version now relaxes those restrictions.
Comment 1 Brandon McConnell 2023-04-11 10:38:28 PDT
For transparency across bug fix implementations/discussions across browser engines:
- WebKit: https://bugs.webkit.org/show_bug.cgi?id=255280
- Mozilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1827404
- Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1432187
Comment 2 Brandon McConnell 2023-04-11 10:45:08 PDT
** One addtl important note— My `200px / 20px` example above uses `px / px`, but imperatively, this should support mixed units as well, so someone should be able to do `100% / 20px` (`% / px`, etc.) to get a number representing how many times the second number fits into the first expression, such as how many times `20px` fits into `100%` of the currently evaluated dimension.
Comment 3 Brandon McConnell 2023-04-12 04:49:44 PDT
Here is a minimal example of this bug:
https://codepen.io/brandonmcconnell/pen/OJByEBO/126b86e86107bda0133813141da9108e

The screen appears red, because of this rule:

```css
main {
  width: 100vw;
  height: 100vh;
  background-color: red;
}
```

However, it should appear blue, due to this style:

```css
main > div {
  width: calc(100% / 20px * 20px);
  height: calc(100% / 20px * 20px);
  background-color: blue;
}
```

The `/ 20px * 20px` should naturally cancel each other out, making those values `100%` once again. This is per the current `css-values-4` spec.

This can also be used, for example, to determine how many times a static number like `25px` fits into a dynamic size like `100vh` and then store that number for use anywhere the number type is accepted.

This will be especially useful once `round()` is implemented (via [#1407473](https://bugs.chromium.org/p/chromium/issues/detail?id=1407473)).
Comment 4 Radar WebKit Bug Importer 2023-04-18 05:40:19 PDT
<rdar://problem/108195400>
Comment 5 Brandon McConnell 2023-07-11 09:35:18 PDT
Any update here? This is essential for many foundational computations in CSS.
Comment 6 Tim Nguyen (:ntim) 2023-07-11 14:24:40 PDT
This looks easy at the surface, but https://github.com/w3c/csswg-drafts/issues/8169 shows some examples where this is not trivial to do.