- From: Steinar H. Gunderson via GitHub <noreply@w3.org>
- Date: Tue, 12 Aug 2025 13:31:42 +0000
- To: public-css-archive@w3.org
sesse has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-mixins-1] How are cycles broken? == Imagine a mixin A that includes an A/B loop: ```css @mixin a() { --last-processed: a; @apply b(); } @mixin b() { --last-processed: b; @apply c(); } @mixin c() { --last-processed: c; @apply b(); } ``` Now suppose someone applies a() within a rule. What is the value of `--last-processed`; a, b, c or even unset? (You could ask similar questions about declarations after the `@apply` rules.) If we're breaking cycles at the last possible moment, then the value is c. This is a fairly simple model; you just keep a stack of everything that is in the process of being applied, and when you see an `@apply` against something already in your stack, you ignore it. However, CSS custom properties don't work that way; they declare the entire cycle as illegal, so `@apply b();` has no effect and the result is a. (Similarly, you could argue that including a cycle is illegal and the value should not even be set, but I don't think that matches CSS custom properties. In any case, they're not quite the same because they have explicit fallbacks.) The problem with this is that we cannot easily rollback already-applied declarations, so before every mixin that we try to apply, we would need a separate cycle-finding step. (We cannot easily do this parse-time, since the mixins may come from different style sheets and/or tree scopes.) So I'd argue that it should be either a or c, but it's not really obvious which one. c is much easier for a performant implementation, though. Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12595 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Tuesday, 12 August 2025 13:31:43 UTC