Re: [csswg-drafts] Proposal: Custom CSS Functions & Mixins (#9350)

> I think being able to reference variables from the outside in mixins is essential.
> * This is how functions work in most programming languages: local vars shadow outside vars, but outside vars are still accessible.

This isn't true, tho. What you're describing is usually called "dynamic scope", where a function can get access to the values of variables in the context it was called. Most languages use "lexical scope", where a function has access to variables in the context it was *defined*, and then when it's called the *only* additional information comes from the arguments themselves. Dynamic scope is very rare these days, as it's both easy to cause weird errors and harder to optimize. Instead we just pass arguments.

(And CSS variables don't exist in the global context in which @function is executed to define the function, so it wouldn't have lexical access to anything.)

Giving functions access to outside variables would also make it more difficult to work with functions generically - every outside variable it references is effectively an extra argument, and one that gets passed implicitly without having to know anything is happening. That means you can't name *your* custom properties arbitrarily, since a function you want to call might also use that property for its own purposes.

(The argument is different for mixins, which definitely swizzle your local "state" already by mixing in more properties. Nothing wrong with allowing *them* the ability to output styles that refer to outside variables.)

> Nesting. Without it mixins can only accommodate the simplest of use cases. It can wait for L2, but the syntax must be designed to allow it.

By this do you mean letting a mixin use nesting to target styles at other elements? Then yeah, absolutely.

> Non-conditional @-rules in mixins. Think of fonts, animations, custom properties, font palettes, @scope etc.

Only insofar as these rules already work when nested inside of style rules. When they do, they should work in mixins; when they don't, they shouldn't.

------

```
@function --at-breakpoints(
  --s: 1em;
  --m: 1em + 0.5vw;
  --l: 1.2em + 1vw;
) returns --result {
  @container (inline-size < 20em) {
    --result: calc(var(--s));
  }
  @container (20em < inline-size < 50em) {
    --result: calc(var(--m));
  }
  @container (50em < inline-size) {
    --result: calc(var(--l));
  }
}
```
I don't see what benefit we gain here from using a (configurable?) custom property here. Could you elaborate on why this is better than just using `@return calc(...)` in each location?

> Being a descriptor allows it to cascade (e.g. to provide alternatives based on browser support — though the utility of that is limited due to var()) 

Right, it can't cascade in that way. We have no idea what the return value *is* - that requires contextual information about exactly how and where it's used, and we don't do that for typed custom properties, so we don't do that here either. The best we can do is know what type it's meant to resolve to, and verify that it does, so DevTools can complain.

> and be type checked like a custom property.

This doesn't require it to be a descriptor. We just need to know the expected type *somehow*.

> `@function --hypot(--a, --b) returns calc(sqrt(pow(var(--a), 2) + pow(var(--b), 2));`

The syntax already allows essentially this:

```
@function --hypot(--a, --b) { @return calc(sqrt(pow(var(--a), 2) + pow(var(--b), 2)); }`
```

> Scoping. We’ve seen time and time again how anything global becomes a pain for authors. If possible, mixins defined within other rules should be scoped to those subtrees, same as a custom property defined in a nested rule. If not possible yet, then we should completely disallow mixins within other rules, so that it can become possible in the future.

This conflicts very heavily with some core concepts, unfortunately. If you have to do selector matching to even know that a mixin is available, that makes it much more difficult to then apply the mixin, and have it interact with the cascade properly.

Disallowing @mixins from being defined inside of style rules is, luckily, the default case - they're not allowed by the Nesting spec unless we say so. ^_^

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9350#issuecomment-1804896681 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Friday, 10 November 2023 00:41:26 UTC