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] max() issue #11768

Closed
nico3333fr opened this issue Feb 24, 2025 · 3 comments
Closed

[css-values] max() issue #11768

nico3333fr opened this issue Feb 24, 2025 · 3 comments

Comments

@nico3333fr
Copy link

nico3333fr commented Feb 24, 2025

Hello there,

I'm Nico, one of Proton Mail/Calendar devs. I encountered an issue on some old browsers that do not support lvh unit in a max comparison, and I'd like to make sure I understood the spec correctly, and if it's the case, to propose something.

I did use something like: block-size: max(3rem, calc((100lvh - 3.75rem - 4.75rem) / 24)) in our codebase.

We discovered that on some old browsers that don't support lvh unit that the max comparison was totally failing. I though first max(3rem, <something not supported>) would go to 3rem, but it seems we must have a consistent type or else the function is invalid https://drafts.csswg.org/css-values/#comp-func

First => could you confirm I properly understood the spec here?

Second => proposal: would it make sense in these cases that when we compare a value and something not supported that the result would default to the properly defined value?

For sure we can wrap stuff in an @support (@supports (block-size: (max(1rem, 100lvh)))) to make sure we support max and lvh (what we did). But TBH, I found it a bit too much, I was thinking that comparing max(3rem, <something not supported>) should go to 3rem, just for graceful degradation/progressive enhancement purposes :)

Thanks,

@Loirooriol Loirooriol added the css-values-4 Current Work label Feb 24, 2025
@Loirooriol
Copy link
Contributor

It's important to keep types consistent, e.g. max(1px, 1deg) doesn't make sense.
But if you use a unit that is not understood by the browser, how is type checking supposed to work?

I think your usecase would be better addressed by

block-size: calc((100lvh - 3.75rem - 4.75rem) / 24);
min-block-size: 3rem;

@tabatkins
Copy link
Member

This is actually failing before the "consistent type" is even checked. See https://drafts.csswg.org/css-values-4/#determine-the-type-of-a-calculation - the unknown unit has a type of "failure", and this percolates up thru the entire expression, causing it to fail to match any of the types like <length>, etc. So this is actually failing at parse time, and causing the declaration to be thrown out.

This is identical to the behavior if you use the unknown unit outside of a math expression: block-size: 100lvh; will also be invalid. We don't really want to automatically mask bugs like this.

There are several ways to deal with this today - an @supports rule testing the use of a unit, or a registered custom property with the desired type and an initial value (the unknown unit will cause it to fail to parse, so it'll become the initial value instead). Once variable units are supported, you can handle this sort of thing very gracefully inline, like:

@property --lvh {
  syntax: "<length>";
  initial: 1vh; /* a dependable fallback */
  inherits: true;
}
:root {
  --lvh: 1lvh; /* the actual value you want to use */
}

...elsewhere...
  block-size: max(3rem, calc((100--lvh - 3.75rem - 4.75rem) / 24));

@nico3333fr
Copy link
Author

@tabatkins thanks for the details, really appreciated. :)

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

3 participants