Re: [csswg-drafts] [css-mixins-1] Expose locals inside apply's contents block (#12631)

@andruud 

> To clarify, what is `--color-from-element` on `<span>` here? (With `--bar` shadowing `--a` locally, as in the previous examples.)

`tomato`, in that example. This also seems reasonable, as if you write this literally:

```css
div {
  --a: gold;
  & > span {
    --color-from-element: var(--a);
  }
}
div > span {
  --a: tomato;
}
```

...you similarly *could* be misled into thinking the `var(--a)` will be `gold`, but since it's a child some other rule could intercept that and rewrite the variable to `tomato`.

(The bit that's a little more confusing is that you *could* apply the contents rule nested deeper into other rules in the mixin, so it *never* draws directly from the applying element even if it's a top-level style in the contents block. But I'm okay with that; I think it'll be a rarer case.)

> Will a contents block passed to a @macro behave the same way as a contents block passed to a @mixin?

Ideally no. If I'm thinking about this correctly, the actual behavior I'm arguing for is that, absent a `using` declaration, variables in contents block are never hygienically rewritten; the `using` declares which variables will *try* to hygienically rewrite themselves (if the mixin has a matching arg or local var). Macros just don't have args or local vars, so they'll never rewrite regardless.

And then my intuition for chaining (and, if I understand correctly, @kizu 's too) is that a `using` decl *sets* the context that it'll rewrite against, with a further `using` having the ability to change that reference. That is, in the following:

```css
@mixin --blues() {
  --c: blue;
  @result {
    background:   var(--a); /* red */
    color:        var(--b); /* green */
    accent-color: var(--c); /* blue */
    @contents; /* no `using`, so it leaves all bindings as set */
  }
}

@mixin --greens() {
  --b: green;
  --c: olive;
  @result {
    @apply --blues() using --c {
      --2a: var(--b); /* green */
      --2b: var(--c); /* blue; */
      @contents;      /* sees the `using --c` and changes its --c binding to --blues() if possible */
    }
  }
}

div.reds {
  --a: red;
  --b: crimson;
  --c: firebrick;
  @apply --greens() using --b --c {
    --1a: var(--a); /* red, guaranteed local */
    --1b: var(--b); /* green, set per --greens() if possible */
    --1c: var(--c); /* blue, also set per --greens() */
  }
}


/* desugars to: */

div.reds {
  --a:          red;
  --b:          crimson;
  --c:          firebrick;
  $greens-b:  green;
  $greens-c:  olive;
  $blues-c:   blue;
  --1a:         var(--a);
  --1b:         var($greens-b);
  --1c:         var($blues-c);
  --2b:         var($greens-b);
  --2c:         var($blues-c);
  background:   var(--a);
  color:        var($blues-b);
  accent-color: var($greens-c);
}
```
(using the convention that `$foo`, which is *not* a valid custom ident, is referring to a hygienic name which is not actually author-visible in styles).

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


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

Received on Wednesday, 25 March 2026 17:18:24 UTC