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-5] if() conditions with calc() comparisons #11104

Open
fantasai opened this issue Oct 28, 2024 · 6 comments
Open

[css-values-5] if() conditions with calc() comparisons #11104

fantasai opened this issue Oct 28, 2024 · 6 comments

Comments

@fantasai
Copy link
Collaborator

Several of the examples in #5009 were comparing <length> values, but this was not included in #10064

Do we want this functionality, and if so what are the use cases and what should be the syntax?

Currently specced conditionals are:

  supports( [ <supports-condition> | <ident> : <declaration-value> ] ) |
  media( <media-query> ) |
  style( <style-query> )
@tabatkins
Copy link
Member

Currently all the conditions in if() are functions; I propose we use the "just parentheses" syntax for this. Namely:

( <calc-sum> <mf-comparison> <calc-sum> )

This way you can write, say, flex-flow: if( (100vw > 200px): row ; else : column; );

(or, spread over multiple lines:

flex-flow: if(
    (100vw > 200px): row;
    else: column;
);

)

@fantasai fantasai added the Agenda+ Later Lower-priority items that are flagged for CSSWG discussion label Oct 28, 2024
@Loirooriol
Copy link
Contributor

if() is defined to resolve at computed-value time. But this needs layout:

width: if( (100% > 200px): max-content; else : stretch; );

So I guess it needs to be invalid? But it would be cool to have an if() as a syntax sugar for arithmetic conditionals, e.g.

width: if( (100% > 200px): 1em; else : 1lh; );
/* behaves like this: */
width: calc(max(0, sign(100% - 200px)) * 1em + (1 - max(0, sign(100% - 200px))) * 1lh)

@tabatkins
Copy link
Member

Yeah, I think you'd need to use a CQ condition to test something similar to that; we need to be able to resolve the condition at computed-value time. I suppose we'd just say that the condition is always false if it uses values that can't be resolved at computed-value time.

I was hoping that if() would subsume the need for a conditional math function, but I guess it doesn't. :/ Gonna be a little hard to explain when exactly calc-if() is needed, unfortunately.


An additional request: the other thing brought up as a common conditional need is just comparing a value to an ident, so you can set a custom property on a component like --style: button and it'll do different things.

I think we can just slot that into the parenthesized syntax, with an <ident> [ '=' | '!' '=' ] <ident> form. It overlaps grammatically with the calc-sum version when you compare calc keywords with each other, but it would resolve the same under either interpretation, so that's fine.

@LeaVerou
Copy link
Member

Why do we need the parens at all? What kind of ambiguity exists if we can simply use bare comparisons? Also, at first, we should probably expand the syntax of style() to allow for comparison operators in addition to :.

@fantasai fantasai added Agenda+ F2F and removed Agenda+ Later Lower-priority items that are flagged for CSSWG discussion labels Oct 29, 2024
@tabatkins
Copy link
Member

tabatkins commented Nov 1, 2024

Why do we need the parens at all? What kind of ambiguity exists if we can simply use bare comparisons?

You need parens to work with the <boolean[]> syntax - the base grammar of a boolean expression must be either parenthesized or functions, in order to match with the <general-enclosed> term that catches future-compat.

We could, in theory, let you omit the parens if you were just doing a single comparison on its own. But then you'd need to add them if you did and/or/not. I'm moderately against the consistency break. Every existing construct that does comparisons uses parens, like @media (width < 600px) {...}

Also, at first, we should probably expand the syntax of style() to allow for comparison operators in addition to :.

That's something for Containment to define; if() just pulls that syntax in. (But yes, we should allow it.)

@LeaVerou
Copy link
Member

Just to add, this would make it possible to use if() with relative colors.

Currently, there is no way to do something like oklch(from var(--color) if(l < .65, var(--dark-math), var(--light-math))).

@astearns astearns moved this from FTF agenda items to Friday morning in CSSWG January 2025 meeting Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Friday morning
Development

No branches or pull requests

4 participants