web-platform-tests / interop

web-platform-tests Interop project
https://wpt.fyi/interop
281 stars 28 forks source link

Unit division and multiplication for mixed units of the same type within calc() #513

Closed scottkellum closed 7 months ago

scottkellum commented 11 months ago

Description

The CSS Values and Units Module has supported division of values of the same type for some time now. This is particularly useful for creating graphs with CSS, applying various styles based on viewport/element widths, and trig functions combined with new anchor positioning.

Example: calc(1rem / 1px) would result in a value of 16 typed as a number assumed type sizes are default.

Specification

https://www.w3.org/TR/css-values-4/#calc-type-checking

Open Issues

Tests

Current Implementations

Standards Positions

No response

Browser bug reports

Developer discussions

Polls & Surveys

No response

Existing Usage

No response

Workarounds

Accessibility Impact

No response

Privacy Impact

No response

Other

No response

foolip commented 11 months ago

@scottkellum do you know what the current behavior of different browsers is here? And are there any tests for this?

foolip commented 11 months ago

@danielsakhapov You've mentioned this behavior before with math functions. Do you know if there are any tests for this in WPT?

scottkellum commented 11 months ago

@foolip All browsers currently fail to calculate anything, invalidating the property.

I do not have any tests for this (or know where to start to find/make them).

Also I found this issue for Chromium by @andruud and will update the issue with it: https://bugs.chromium.org/p/chromium/issues/detail?id=1213338

brandonmcconnell commented 11 months ago

100% on board for this. It's attainable, a no-op, and it's fully spec'd 💯

I've been fighting for this one for years, so seeing this here is super exciting.


Here are some addtl resources… (expand/collapse) 👋🏼 --- ### For use under "Open issues" heading ````markdown - https://github.com/w3c/csswg-drafts/issues/7448 ```` > This is the primary GitHub discussion surrounding this feature, as it may help to mention it. --- ### For use under "Browser bug reports" heading ````markdown - 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 ```` > Feel free to re-use any of my notes from these bugs ☝🏼 if it'll help build out this issue. I would love to see this implemented and will help however I can. --- ** One last sidenote — it may help people to more easily find/understand this issue's purpose if you include the "mixed units" keyword in. the title 🙂 ---

Thanks for submitting this, Scott!

thebabydino commented 11 months ago

This has to be one of my top CSS wishes. I detailed a use case in this thread https://twitter.com/anatudor/status/1537881090223853568

scottkellum commented 11 months ago

Thanks for the notes @brandonmcconnell, that was super helpful and I made updates.

brandonmcconnell commented 11 months ago

@scottkellum Sure thing! I also just noticed that there was an update on my WebKit bug ticket with another GitHub discussion link, which had its own related issue, so here are a couple more:

scottkellum commented 11 months ago

Linking related people involved with this spec and implementation. I’m sure I’m missing a lot in the original post and would love some help filling things out and improving reach/visibility of this issue. (again, thanks @brandonmcconnell for assistance here!)

Spec and related discussions:

Browser bug report owners

nmn commented 11 months ago

I've been asking for this since before Container Queries were even considered possible. This combined with the round() function will be hugely useful!

kizu commented 11 months ago

I want to add one article for the “workarounds” field: https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j by @propjockey

It would be awesome to not rely on hacks like tan(atan2(…)) to achieve this. There is also at least one other workaround for this, even more involved (I'll share it here as well, when I'll finish my article about it).

gsnedders commented 11 months ago

Tests

No response

I can't find any, at least. And I guess https://github.com/w3c/csswg-drafts/commit/ea66912c7bf8db5036d428450e6f34c1c9b6c2af predates the CSS WG having any policy requiring tests for specs as they progress.

foolip commented 11 months ago

We (Google) think this is a strong proposal and the use case is clear, but without tests, we can't create a focus area with a score to track progress. We don't expect Interop proposal authors to write specs or tests, so this is not a criticism of the proposal, but someone would need to put in a significant effort in a short amount of time for this to work out.

brandonmcconnell commented 11 months ago

@foolip Do you have examples of tests for similar/related features so I can see all that it would entail to create tests for this proposal?

If someone can list out what a solid list of tests would be for this, maybe a few of us can come together to split the load.

If the tests will need to be written in C/C++, my help may be more limited, but I can still try to lend a hand.

What is the deadline for these tests?

nt1m commented 11 months ago

@brandonmcconnell Here are tests for this year's math functions focus area:

https://wpt.fyi/results/css/css-values?product=chrome&product=firefox&product=safari&aligned=&view=interop&q=label%3Ainterop-2023-mathfunctions&label=master&label=experimental

Code at: https://github.com/web-platform-tests/wpt/tree/master/css/css-values

nt1m commented 11 months ago

It would be preferable to contribute those as separate tests rather than extending the existing ones.

brandonmcconnell commented 11 months ago

@nt1m Thanks. It's a rough first pass on my part, but something to get the ball rolling:

https://github.com/web-platform-tests/wpt/pull/42517

foolip commented 11 months ago

Thanks @brandonmcconnell for contributing tests, that's great! You asked about a deadline, and Nov 30 is when we expect to make most of the preliminary decisions of what to include and not in Interop 2024. Participating organizations (like Google) will need to make an internal decision earlier than this, however.

I'll ask around for someone to review the tests, and I think there will be enough time in the end.

thebabydino commented 11 months ago

Starting from the atan2() hack, I've done something awful...

I was curious if

tan(atan2(atan2(var(--dj), var(--di)), 1turn))

would work so we can then use it in an animation-delay value... and it does!

Demos: one, two, three

scottkellum commented 11 months ago

@thebabydino I’ve been using it in animation-delay as well and can confirm this workaround works well! https://codepen.io/scottkellum/pen/ZEVPMav

It would be nice if value typing were implicit rather than explicit. I had expected it to implicitly work as things like calc(2vw + 0.8rem) work without explicitly stating what type the value is.

foolip commented 11 months ago

https://github.com/web-platform-tests/wpt/pull/42517 has just landed. There haven't been full runs of WPT yet, but the results can be seen here: https://wpt.fyi/results/css/css-values?label=pr_head&max-count=1&pr=42517

brandonmcconnell commented 11 months ago

@scottkellum Here are the new tests

### Tests

- [css/css-values/getComputedStyle-calc-mixed-units-003.html](https://wpt.fyi/results/css/css-values/getComputedStyle-calc-mixed-units-003.html)
- [css/css-values/calc-in-media-queries-with-mixed-units.html](https://wpt.fyi/results/css/css-values/calc-in-media-queries-with-mixed-units.html)
dandclark commented 7 months ago

Thank you for proposing Unit division and multiplication for mixed units of the same type within calc() for inclusion in Interop 2024.

We wanted to let you know that this proposal was not selected to be part of Interop this year.

We believe this proposal is too broad, and that as such, Interop 2024 is not the right venue to do this focus area.

For an overview of our process, see proposal selection. Thank you again for contributing to Interop 2024!

Posted on behalf of the Interop team.

brandonmcconnell commented 7 months ago

@dandclark I'm not sure how this proposal could be any narrower. It's also worth noting that this is not a proposal but an arithmetic bug that exists in nearly every browser right now.

Most if not all modern browsers perform math incorrectly according to the official spec. This interop issue seeks to align browsers with the official current spec.

This one bug is also a major blocker for several other features dependent on CSS's ability to execute math correctly.

I would urge the interop selection team to seriously reconsider this.

nt1m commented 7 months ago

I don't know why this answer was picked for this issue, it was just that this wasn't high priority enough compared to the accepted proposals.

brandonmcconnell commented 7 months ago

@nt1m Any idea when this fix would be implemented. At the moment, most/all modern browser perform basic math with mixed units incorrectly, which also blocks quite a few other proposals. That is all this PR seeks to achieve.

nt1m commented 7 months ago

That's up to each browser vendor.

Loirooriol commented 7 months ago

Note this is not "an arithmetic bug", it's a new feature from CSS Values 4. CSS Values 3 didn't allow dividing by dimensions.

brandonmcconnell commented 7 months ago

@Loirooriol Yes, arithmetic in its current implementation does not match the latest spec, CSS Values 4. That is all I meant.

scottkellum commented 7 months ago

From what I've gathered over my years lobbying for this is that it is likely not going to see traction until one vendor picks it up. Once one vendor picks it up it will create more use cases and browser inconsistencies to get more traction with interop. I hope a vendor picks this up. This is a somewhat abstract feature so while it's incredibly useful, the use cases are often not as straightforward as other features.

I'm disappointed this didn't make it in as I would find this incredibly useful. I'll try again next year. Really appreciate everyone in this thread and especially @brandonmcconnell for pushing to give this proposal a fighting chance.

nmn commented 7 months ago

I can provide use-cases if that helps prioritise this feature.

danielsakhapov commented 7 months ago

Note that the full support for the typed arithmetic would require a solid rewrite of the math representation for all web engines. Nevertheless, I feel like a workaround using progress*() functions can be used for now and is easier to implement for web engines. https://drafts.csswg.org/css-values-5/#progress https://wpt.fyi/css/css-values/progress-computed.tentative.html

nmn commented 7 months ago

Note this is not "an arithmetic bug", it's a new feature from CSS Values 4. CSS Values 3 didn't allow dividing by dimensions.

While this is technically true, it should be noted that it is already possible to divide lengths in CSS in all modern browsers using tan(atan2(length1, length2)).

This approach has been detailed in this blog post.

Now, as the blog post mentions, there are "arithmetic bugs" when using this approach in all of the browsers which can be worked around by using CSS variables with number types etc.

So, even if calc isn't improved to support scalar division as is specced in CSS Values 4, can we at least prioritise fixing the bugs when using tan(atan2(length, length)) so it can be used in the meantime?

trollkotze commented 5 months ago

While this is technically true, it should be noted that it is already possible to divide lengths in CSS in all modern browsers using tan(atan2(length1, length2)).

No, it isn't.

Now, as the blog post mentions, there are "arithmetic bugs" when using this approach in all of the browsers which can be worked around by using CSS variables with number types etc.

So there is no division by dimensions here.

nmn commented 5 months ago

No, it isn't.

Did you even see the link? There are actual examples of the technique being used to divide dimensions. And it works. It's just hacky. It is supported.

brandonmcconnell commented 5 months ago

@nmn are there any similar techniques you know of for multiplication?

nmn commented 5 months ago

@brandonmcconnell

Multiplication of two lengths doesn't make sense, as you'd get area units.

10px / 1px === 10 without a unit. But 10px * 1px === 10(px^2) px^2 is an invalid unit as we do not units for areas in CSS.

If you need multiplication of two lengths, you'd always need to divide by a length as well to get a proper length unit. For such scenarios, you can just divide first as multiplication/division is associative.