- From: Brandon McConnell via GitHub <sysbot+gh@w3.org>
- Date: Thu, 13 Oct 2022 21:09:15 +0000
- To: public-css-archive@w3.org
brandonmcconnell has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-conditional] `fallback()` function == # The problem I just recently became more increasingly aware of how CSS doesn't provide a built-in method for providing fallback values, outside of what's currently supported within [`var()`](https://w3c.github.io/csswg-drafts/css-variables-1/#using-variables) and what's coming to [`attr()`](https://github.com/web-platform-tests/interop/issues/86). With this in mind, if I wanted to provide multiple fallback values for an expression based on the first that works, the general approaches are these— 1. **Declare the property multiple times, in priority order (ascending):** ```css element { color: black; color: currentcolor; color: color(display-p3 1 0 0.87); } ``` 2. **Custom properties** If, however, you want to bring custom properties into the mix, it suddenly becomes a bit more complicated, as `var()` always validates as truthy, so you instead need to rely on `var`'s built-in fallback value. ```css element { color: var(--property-1, var(--property-2, var(--property-3, black))); } ``` As is clear in the second example above, nesting in this way can get pretty messy, not to mention that this method doesn't support multiple fallback values taking into current account browser support. With the same type of nesting and incorporating the [`if()`](https://github.com/w3c/csswg-drafts/issues/4731) function currently being discussed, it might look something more like this: ```css element { color: var(--property-1, var(--property-2, var(--property-3, if(supports(background: color(display-p3 1 0 0.87)), color(display-p3 1 0 0.87), black)))); } ``` This same pattern could be used to implement colors in color spaces many browsers don't support, and that's still just one example using color for the sake of this example. And still… this example is awfully messy. # Description of the proposal I propose adding a `fallback()` (or something similar; I'm not sold on the name), which takes a list of values and returns the first value that doesn't error out (or that doesn't return an undefined value). ### Syntax ```css fallback(value1 [, value2?, value3?, ..., valueN?]) ``` ### Usage ```css element { color: fallback(--property-1, --property-2, --property-3, color(display-p3 1 0 0.87), black); } ``` It's important to note, as my previous examples might be found misleading, that this would **_not_** change the existing functionality of `var()`. Take for example the _same_ example from above, but wrapping each custom property name with `var()`: ```css element { color: fallback(var(--property-1), var(--property-2), var(--property-3), color(display-p3 1 0 0.87), black); } ``` Because `var()` always validates as truthy, the above example would always evaluate to `var(--property-1)` even if its value is undefined. This is important so as, not to clash with the existing functionality of `var()`. This is still helpful, as variables can still be used with their own fallback values if the variable value is undefined. As such, these two would be equivalent ✅ ```css element { color: fallback(--property, color(display-p3 1 0 0.87), black); } element { color: fallback(var(--property, color(display-p3 1 0 0.87)), black); } ``` These two are not ❌ ```css element { color: fallback(var(--property, color(display-p3 1 0 0.87)), black); } element { color: fallback(var(--property), color(display-p3 1 0 0.87), black); /* └→ always evaluates to var(--property-1) */ } ``` So generally, speaking, this: ```css element { color: fallback(--property, color(display-p3 1 0 0.87), black); /* ✅ */ } ``` …would be preferred over this: ```css element { color: fallback(var(--property, color(display-p3 1 0 0.87)), black); /* 🤷🏻♂️ */ } ``` …though I can certainly foresee IRL examples where the latter would be what is _evaluated_ (but not actually _used_) simply because one variable value used inside `fallback()` has its own fallback value already. For example: ```css parent { --default: color(display-p3 1 0 0.87); --property: var(--default, color(display-p3 0 1 0.87)); element { color: fallback(--property, black); } } ``` This would be perfectly acceptable and would be the equivalent of this: ```css parent { element { color: fallback(color(display-p3 1 0 0.87), color(display-p3 0 1 0.87), black); } /* ↑ ↑ ↑ --default --property black */ } ``` Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7881 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Thursday, 13 October 2022 21:09:18 UTC