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] Make it explicit that min(), max(), clamp() require arguments to have the same type #7496

Closed
Loirooriol opened this issue Jul 14, 2022 · 7 comments
Labels
Closed Accepted as Editorial Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-values-4 Current Work

Comments

@Loirooriol
Copy link
Contributor

round(), mod(), rem(), hypot() are defined with

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

I think the same applies to min(), max() and clamp(), but https://drafts.csswg.org/css-values-4/#comp-func doesn't say that.

It may not be actually needed, since https://drafts.csswg.org/css-values-4/#calc-type-checking already says

For each of the above, if the type is failure, the math function is invalid.

But for round(), mod(), rem() and hypot() it's stated in both places and it's more clear. So I would do the same for min(), max() and clamp().

Also, these could be merged:

or separate hypot() (exponential function) from the stepped value functions.

@Loirooriol Loirooriol added the css-values-4 Current Work label Jul 14, 2022
@tabatkins
Copy link
Member

Yeah, those were just written at different times so I ended up with slightly different editorial conventions. Happy to align them.

@NerdyDeedsLLC
Copy link

NerdyDeedsLLC commented Aug 27, 2022

@Loirooriol , @tabatkins, forgive me for interjecting this into an Editorial story, but it is related and, based on the umpteen other tangentially-related issues I've read, you two are apparently some of the most-informed people on Earth regarding this topic, specifically.

I've been combing through the spec trying to work out why one cannot get a <number> type result from a clamp(). I can see that this is the case, to be sure, but not necessarily why it should be. As Loirooriol states above, this is clearly the intention, so i assume there's some deep-dark gotcha endemic to the problem, but nothing I've found says what it IS. That is to say:

Presupposing I have a couple simple calculations I'm performing... say:

/* 0px or 1px, based on if my viewport's width > 1024px */
    --pixelResult : clamp( 0px, calc( 100vw - 1024px ), 1px );  

/* 0% or 100%, based on if --pixelResult != 0 */ 
    --prcntResult : clamp( 0%, calc( var(--pixelResult) * 9999 ), 100% ); 

...both by necessity result in a <length> (based, I'm assuming, on the serialization process the calculation undergoes, and the necessity of a cohesive value, being the result of the min/max clamp is functionally syntactic sugar for?).

But my question amounts to: is there a reason the specification avoids the ability to get a <number> result (other than, of course, the syntax not currently supporting same, natch)? I'm sure you can see where I'm going with this, but, is there any particular reason one SHOULDN'T be able to get what amounts to a boolean test out of the calc/clamp "test" above? The example is contrived, I know, but I've no doubt you follow me here: there's plainly a comparative test being performed, if only a mathematical computation, but if the user is specifying the over/under values anyway, why not permit hidden/visible or relative/absolute as the result? Even just a <number> 0 / 1 would be useful (I cannot apply --prcntResult in an opacity or a rgba(), as a for-instance).

I grasp this particular scenario would be better resolved with media queries - again: contrived example - but it seems like it would offer a great deal of flexibility when dealing with two elements whose dimensional characteristics change during runtime (deriving a UI scale factor based on the largest entry in a word cloud, for an off-the head example, for instance).

Again, please forgive my using this as the venue for asking this; it's literally simply the first related topic where you two specifically were the only conversants. I'm just now starting to dabble into the specification sector; if there is a more appropriate place to inquire/discuss/advocate after such things (I'm certain there is), and if you'd be so kind as to point me that way, I'll delete this comment and get out of your hair.

In any event, thank you both, truly, for all you both do. It's people like you that are literally carrying the web's forward progress on your backs. I've nothing but mad respect for you both.

@Loirooriol
Copy link
Contributor Author

one cannot get a <number> type result from a clamp()

You can, if the arguments are <number>s. Like in clamp(0, (100vw - 1024px) / 1px, 1), but see below.

both by necessity result in a <length>

The 1st one is a <length>. The 2nd one mixes length and percentage arguments, so it will be a <length-percentage> in properties like width that resolve percentages against lengths, or it will be invalid in properties like opacity.

0px or 1px

The numeric part of a length is not necessarily integral, you can also get 0.5px and such. So this is not good for boolean logic.

one SHOULDN'T be able to get what amounts to a boolean test

clamp() is not the right tool for that, sign() is better: #4673, #4731 (comment)

why not permit hidden/visible or relative/absolute as the result?

You mean keywords? Thanks to sign() you can use arithmetic to fake conditionals with numeric values, but keywords will probably have to wait for proper conditionals.

@tabatkins
Copy link
Member

Yeah, having a numeric comparison function is reasonable; see the (long) discussion in #5009 going over the options (of which we probably want to pursue several). In particular, see #5009 (comment) for my summary of the discussion.

I haven't gotten around to working on that yet, but I (or someone else, maybe Lea) will at some point.

@tabatkins
Copy link
Member

Edits done, lmk if these suffice, @Loirooriol

@Loirooriol Loirooriol added Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. and removed Commenter Response Pending labels Oct 10, 2022
@brandonmcconnell
Copy link

@tabatkins @Loirooriol I think I already understand this from the comment, but I wanted to confirm— this change still permits different units so long as they evaluate to the same syntax/type, so this would still be valid, right?:

some-element {
  width: clamp(100px, 200px + 15vw, 100%)
}

@Loirooriol
Copy link
Contributor Author

Yes, the 3 arguments have type «[ "length" → 1 ]» so it's valid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted as Editorial Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-values-4 Current Work
Projects
None yet
Development

No branches or pull requests

4 participants