- From: Brandon McConnell via GitHub <sysbot+gh@w3.org>
- Date: Mon, 26 Sep 2022 15:03:24 +0000
- To: public-css-archive@w3.org
> There is a more fully fledged [custom function proposal in Houdini](https://github.com/w3c/css-houdini-drafts/issues/857) where the function will be defined in JS. I think that proposal would solve most of your needs.
**UPDATE:** I want to clarify— my main goal here in voicing my recommendations is evolving CSS itself and empowering CSS developers to build and use powerful functions with ease without **_needing_** to use JS if they so choose. Houdini is certainly the primary solution to the most complex use cases.
I'm certainly not suggesting CSS `@custom-function` cover all possible use cases, but if we can build CSS functions to be more powerful and flexible, I think we'd make them much more desirable to use for anyone. In many cases, it may be even simpler and more sensible to write a style-specific function in CSS rather than Houdini.
Even more important than utility cases, some of my recommendations such as using `@return` vs. `result` are more focused on the scalability of `@custom-function` rather than semantics. `result` works for the present use case of var substitution, but it could be harder t use for more logically-sophisticated use cases, whereas `@return` opens the door to better logic and short-circuiting and the future growth of `@custom-function`.
---
<details>
<summary><code>result</code> vs. <code>@return</code> examples & reasoning</summary>
<br />
In short— using `@return`:
```css
@custom-function (...) {
@if (...) {
@return 1; /* <-- this value gets used if the condition is true, per short-circuiting */
}
@return 2;
}
```
whereas, with `result`:
```css
@custom-function (...) {
@if (...) {
result: 1;
}
result: 2; /* <-- this value ALWAYS gets used, per the cascade, even if the condition is true */
}
```
To support short-circuiting in this style, we're forced to use the `@else` clause, even if undesirable.
```css
@custom-function (...) {
@if (...) {
result: 1;
} @else {
result: 2;
}
}
```
For some use cases, this could seem a bit tedious, especially if you want to short-circuit before the bulk of the function's logic.
This…
```css
@custom-function (...) {
@if (...) {
@return "";
}
/* LOTS of logic here */
}
```
…becomes…
```css
@custom-function (...) {
@if (...) {
result: "";
} @else {
/* LOTS of logic here */
}
}
```
</details>
---
<details open>
<summary>Houdini vs. <code>@custom-function</code> examples & other notes</summary>
<br />
Here is an example of what an if-statement custom function might look like when composed with Houdini, pulled from the related [proposal discussion](https://github.com/w3c/css-houdini-drafts/issues/857)…
### JavaScript (via Houdini)
```js
class ConditionalEvaluation {
static get genericTypeArguments() { return ['<T>']; }
static get inputArguments() { return ['<boolean>', CSS.CustomFunction.lazyArgument('<T>'), CSS.CustomFunction.lazyArgument('<T>?')]; }
static get returnType() { return '<T> | <null>'; }
conditional([condition, ifTrue, ifFalse], styleMap) {
if(!!condition) {
return CSS.CustomFunction.evaluate(ifTrue);
} else if (ifFalse) {
return CSS.CustomFunction.evaluate(ifFalse);
} else {
return null;
}
}
}
registerCustomFunction("--if", ConditionalEvaluation, "conditional");
```
vs. the same example built using `@custom-function`…
### CSS `@custom-function`
```css
@custom-function --if(--condition "<boolean>", --ifTrue "<T>", --ifFalse "<T> | <null>") "<T> | <null>" {
@if (var(--condition)) {
@return var(--ifTrue);
}
@return var(--ifFalse);
}
```
Here, the CSS implementation is just as explicit in terms of arg/return types (syntax) and less verbose.
Both can be invoked like this:
```css
:root {
/* storing boolean value in custom property */
--is-dark-mode: media(prefers-color-scheme: dark);
}
selector {
/* exclude `ifFalse` value to omit rule if `condition` is false */
background-color: --if(var(--is-dark-mode), "black");
/* boolean evaluation inline */
--element-width: 50px;
content: --if(var(--element-width) < 32px, "small", "large");
}
```
</details>
---
--
GitHub Notification of comment by brandonmcconnell
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7490#issuecomment-1258175184 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 26 September 2022 15:03:26 UTC