- From: Johannes Odland via GitHub <sysbot+gh@w3.org>
- Date: Tue, 12 Jul 2022 18:24:17 +0000
- To: public-css-archive@w3.org
johannesodland has just created a new issue for https://github.com/w3c/csswg-drafts:
== Custom mathematical functions ==
@tabatkins mentioned the idea of custom mathematical functions in a [comment on the custom units issue](https://github.com/w3c/csswg-drafts/issues/7379#issuecomment-1170415284):
> Like, pretend for a moment that we have simple custom functions, like:
> 
> ```css
> @custom-function --fluid(--value) {
>   arg-syntax: --value "<number>";
>   result: clamp(1rem, var(--value) * 1vw, var(--value) * 1rem);
> }
> ```
This seems too good to not follow up on. Custom functions would make it possible to write more readable css with less repetition. 
### Background
We can already increase readability and reduce repetition of mathematical expressions by using function like custom properties, as @mirisuzanne describes in [her excellent article on CSS Custom Properties In The Cascade](https://www.smashingmagazine.com/2019/07/css-custom-properties-cascade/). _This is available in browsers today_. 
There are however limits to what we can do with function-like custom properties, and there are issues with their readability.
**Example**
The following expression returns 0% at a minimum viewport size of 375px, and 100% at a maximum viewport size of 1920px. 
```css
clamp(0%, 100% * (100vw - 375px) / (1920px - 375px), 100%)
```
We could give this expression semantic meaning and reuse it almost everywhere by declaring it as the value of a custom property:
```css
* {
    --min-width: 0px;
    --max-width: 2560px;
    --fluid-ratio: clamp(0%, 100% * (100vw - var(--min-width)) / (var(--max-width) - var(--min-width)), 100%);
}
```
This custom property could then be used with "arguments" where needed: 
```css
p {
  --min-width: 375px;
  --max-width: 1920px;
  font-size: mix(var(--fluid-ratio), 1rem, 1.25rem);
}
```
This is great, and should work in browsers today (except for divide by unit, that is specified in css-units-4 but not supported yet).
There are some limitations to this approach:
1. It's not possible to read from the rule that `--min-width` and `--max-width` are arguments for `--fluid-ratio`, nor that `--fluid-ratio` is a function like custom property. 
2. We would run into trouble if we wanted to reuse the same "function" with separate parameters.
```css
p {
  /* This would not work. (Arguably a constructed example) */
  --min-width: 375px;
  --max-width: 1920px;
  font-size: mix(var(--fluid-ratio), 1rem, 1.25rem);
  --min-width: 375px;
  --max-width: 700px;
  padding: mix(var(--fluid-ratio), 1rem, 2rem);
}
```
### Proposal
Add syntax for custom mathematical functions. The syntax could follow the example from @tabatkins comment with an at-rule to declare the function and the syntax of its arguments:
```css
@custom-function --fluid-ratio(--min-width, --max-width) {
   arg-syntax: --min-width "<length>", --max-width "<length>";
   result: clamp(0%, 100% * (100vw - arg(--min-width)) / (arg(--max-width) - arg(--min-width)), 100%);
} 
```
The custom function could then be used where mathematical expressions can be used:
```css
p {
  font-size: mix(--fluid-ratio(375px, 1920px), 1rem, 1.25rem);
  padding: mix(--fluid-ratio(375px, 700px), 1rem, 2rem);
}
```
There are probably many reasons why this would be annoying or impossible to implement, but hopefully there's smarter people than me out there that can come up with a way to solve custom functions. 
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7490 using your GitHub account
-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Tuesday, 12 July 2022 18:24:19 UTC