[csswg-drafts] [css-values] Iverson bracket functions (#4731)

jimmyfrasche has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-values] Iverson bracket functions ==
I propose three mathematical functions inspired by [Iverson bracket notation](https://en.wikipedia.org/wiki/Iverson_bracket) — if(p), media(q), supports(s) — that can only be used within calc() and always return either 0 or 1. This is useful for concisely toggling terms on or off in an expression, like `width: calc(500px + 10px*media((width > 800px)))`.

media() is simple to define by example:
```css
:root {
  --dur: calc(5s * media((prefers-reduced-motion)));
}
```
is equivalent to
```css
:root {
  --dur: 5s;
}
@media (prefers-reduced-motion) {
  --dur: 0s;
}
```
and similarly for supports(). If the media or feature query match, evaluate to 1. If it fails to match or is not recognized, evaluate to 0. 

if() is similar but work on expressions logical and comparative expressions involving var(), env(), and attr(), like:
```css
if(var(--x) = 1)
if(2*var(--x) < abs(env(--y)) <= 80)
```

I am leaving this somewhat loosely defined. There are a lot of cases to consider I'm not sure what the best solution is for all of them. Should non logical/relation expressions be allowed? That is, should `if(2*var(--x))` evaluate to 1 if it the inner expression is computed to be nonzero or does there need to be an explicit comparison? An if() that contains an undefined var/env or unset attr should evaluate to 0 but should there also be another bracket function like `defined(var(--x))`? Should non-numbery variables always cause evaluating to 0 or should `if(var(--state) = paused)` be allowed?

For defined purely numeric cases, if() can be emulated with inventive combinations of arithmetic and min, max, clamp, abs, sign, round, mod, and rem but it gets fairly nasty even for relatively simple cases and even if you follow what's going on it lacks readability.

#3455 was a previous attempt at an if(). It was deemed too powerful. It was different from the current proposal in two ways:
1. it allowed the condition to refer to properties of the element (current width, etc.)
2. it was a ternary operator returning arbitrary values

I suspect that 1 is the entirety of the argument for it being too powerful, though I am unsure. If this is case, this proposal can be extended by dropping the requirement that these must be in calc() and giving them optional parameters so that
```
if(p) - returns 1 or 0
if(p, then) - returns then or 0
if(p, then, else) - returns then or else
```
And possibly similarly for media and supports, though that could require disallowing "," within the media query itself. Although note that if nonzero is considered true then you could leave media() and supports() unchanged and use `if(media(q), then, else)`.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4731 using your GitHub account

Received on Sunday, 2 February 2020 20:31:00 UTC