- From: Lea Verou via GitHub <sysbot+gh@w3.org>
- Date: Wed, 18 Oct 2023 19:39:17 +0000
- To: public-css-archive@w3.org
Coming to this quite late (I only discovered it yesterday from @mirisuzanne’s mention in #8738). Sharing some thoughts below. ## Commonalties between mixins and functions I’m not sure about defining functions and mixins together. They have fundamentally different use cases, and I’m worried defining them together could hold one of them back from its full potential. - Functions are about computation reuse: you provide input values, you get an output value. It makes sense for them to be side effect free, just like native CSS functions. - Mixins are about style reuse. They have input but no output. They (ideally) need access to the context, and the full power of CSS. I'd suggest the opposite process: iterate on them *separately* then find the common concepts and spec those together at the end. ## Use cases For both mixins and functions, there are two fundamental use cases, and we need to ensure both are served well: 1. Local, specific purpose mixins and functions to reduce coupling and duplication and facilitate maintainability within a stylesheet 2. Libraries of mixins and functions intended to be imported in projects and be more broadly useful. Examples: These are a spectrum. One may start with a local mixin/function, then decide that they are more broadly useful. An observation is that mixins also facilitate **encapsulation**. Today if you have multiple classes that share styling, either you need to alter the structure of your CSS code, OR just ask people to use *both* the base class and the more specific classes (e.g. `class="callout warning"`). [Bootstrap icons](https://icons.getbootstrap.com/) does the latter too: every icon needs *both* a `.bi` class, AND a `.bi-{icon id}` class . Mixins can facilitate this both internally, by having a local `--bi` mixin, but also by exposing all icons as mixins. There could even be mixins like `--icon-before` and `--icon-after` so that people can apply them directly. ## Requirements ### Must-have, even in the MVP - I think being able to reference variables from the outside in mixins is *essential*. 1. This is how functions work in most programming languages: local vars shadow outside vars, but outside vars are still accessible. 4. As @kizu mentioned, there are plenty of very valid use cases. 5. Easier to debug 6. If outside vars are accessible, one can always get the behavior in the current proposal by setting them to `initial` in the mixin, but if they are not there is no way to get the opposite behavior 7. It’s probably fine if functions have to be side-effect free, since mixins can always be used instead, when context is needed. ### Must-have, but we *could* be left out in L1 if really needed - 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. - Scoping is also very important. - Non-conditional @-rules in mixins. Think of fonts, animations, custom properties, font palettes, `@scope` etc. ### Important but not essential - 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. ## Syntax ### Mixins The current syntax proposed uses a `@mixin` rule to define the mixin and an `@apply` rule to apply it. I suspect it may not be feasible implementation-wise, but I would really love to investigate whether using a property-like syntax would be possible for *using* the mixin. Instead of parentheses, the parameters would be passed in as a property value. I will open a separate issue for this, as it seems a significant deviation from this proposal. ### Using parameters in conditional rules The proposal asserts that we could not use `var()` to refer to parameters in conditional rules. @tabatkins can correct me but I think we could simply allow them in the grammar, and have prose that only permits them in mixins, only when they refer to params passed? ### Function return value: @-rule or descrptor? > I like an at-rule syntax (e.g. `@return`) rather than a `result` descriptor. > > - It helps distinguish the final returned value from any internal logic like custom properties and nested rules > - Result is not a property, but looks a lot like one It’s more of a property than an `@-rule` IMO. It's something that has a value and (optionally) a type. There is no precedent for @-rules that have values and types, but plenty for descriptors. Yes, a generic @-rule is more distinguishable than a descriptor, but that is a syntax highlighting problem, not a language problem. 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()`) and be type checked like a custom property. Actually, come to think of it, do we even *need* a dedicated descriptor? What if the result was held by a custom property, and which one was part of the function definition: ```css @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)); } } ``` And I like @FremyCompany’s idea as a default: if `returns` is missing, use the custom property that is named the same as the function. Oh, or what if what it returns is actually a proper value? ```css @function --hypot(--a, --b) returns var(--result) { --result: calc(sqrt(pow(var(--a), 2) + pow(var(--b), 2)); } ``` Then you can make the braces optional and have a shortform function definition: ```css @function --hypot(--a, --b) returns calc(sqrt(pow(var(--a), 2) + pow(var(--b), 2)); ``` ## Questions Do mixins cascade down Shadow DOM boundaries? If so, they may help fix the issue of styling Shadow DOM (e.g. having form controls that are styled like the surrounding page with reasonable DX). -- GitHub Notification of comment by LeaVerou Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9350#issuecomment-1769202142 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Wednesday, 18 October 2023 19:39:19 UTC