🚨 Want mixins in CSS?
Help the @csswg by telling us what feels natural to you!

Look at the code in the screenshot. What resulting widths would you find least surprising?

A: All get 100px
B: div gets 100px, div > h2 gets 200px, div + p gets 300px
C: div gets 100px, div > h2 gets 200px, div + p gets no width*
D: div and div > h2 get 100px, div + p gets no width*

* from the mixin

Poll in https://front-end.social/@leaverou/116297811172593173

Please answer based on what feels natural *to you*, it's not a quiz.

A (All 100px)
B (100px, 200px, 300px)
C (100px, 200px, nothing)
D (100px, 100px, nothing)
Poll ends at .
Lea Verou, PhD (@[email protected])

Attached: 1 image 🚨 Want mixins in CSS? Help the @[email protected] by telling us what feels natural to you! Look at the code in the screenshot. What resulting widths would you find least surprising? A: All get 100px B: div gets 100px, div > h2 gets 200px, div + p gets 300px C: div gets 100px, div > h2 gets 200px, div + p gets no width D: div and div > h2 get 100px, div + p gets no width Poll in https://front-end.social/@leaverou/116297811172593173 Please answer based on what feels natural to you, not what the current proposal says.

Front-End Social

@leaverou

(now that I understand what you were asking)

C & D seem yick.

I can see justification for A & B either way. I like/voted A since there could be simple optimizations available and it's less likely to do surprising things, which I might worry about if the order switched to:

div > h2 { font-size: 20px; }
div + p { font-size: 30px; }
div { @apply --foo(10em); font-size: 10px; }

But ideally, I'd go with option E, "have the browser reach through the screen and smack the web-dev with a pool noodle" 😆

@gumnos All four options would produce the same results for the order in your toot.

@leaverou I'm not clear where the "nothing" option comes from. Is the idea that since the `+ p` isn't a descendent of the div it can't inherit anything from the mix-in? I don't see why that would make sense unless you're going to make all nesting work like that.

For the other two options, I can see use cases for both wanting the argument to the mix-in to resolved at the time the mix-in is applied, or only in the final rule. Maybe support syntaxes for either?

@AmeliaBR @leaverou That is already possible with the current syntax. See https://github.com/LeaVerou/blog/discussions/137#discussioncomment-16340589 for details :)
What mixin behavior feels most natural to you around nested rules? · LeaVerou blog · Discussion #137

🚨 Want mixins in CSS? Help the CSS WG by telling us what feels natural to you! Look at this code: @mixin --foo(--arg <length>) { @result { &, & > h2, & + p { width: var(--arg); } } } div { @apply -...

GitHub

@bramus @leaverou Oh, that does make sense & solves both use cases. Define the argument as a `<length>` to cause any passed in values to be converted to an absolute length before use, but leave it untyped to use the token as specified.

It's something that would need good notes & examples in the spec, but now I understand the reasoning, I agree that it's logical.

Somewhat related: any progress on defining a CSS type notation for untyped custom properties etc? <token-stream>?

@leaverou I also took a look at what a Sass mixin would create (and how that compiled CSS would effect the HTML)

@leaverou
Voted B for raw/intent-values.
Voting E for computed values/layout pass:
- div > h2 is constrained by the parent div to 100px, so it shouldn't grow larger than the containing div
- div + p however isn't constrained by the 100px div, but by their shared parent, so the p could be at most 300px.

TL;DR: div 100px, h2 200px, p 300px; but div > h2 constrained to 100px, div + p at most 300px

@leaverou I voted A, because —arg is defined as type <length>. I would vote B for untyped —arg.
Because this what @-function does and I would expect @-mixin to work the same way, in terms of resolving em to px or not.

Example (only work in Chrome): https://codepen.io/ziadkh0/pen/WbGdWdb

@function typed vs untyped

...

@leaverou To those finding this thread: before you vote 100-200-300, hear me out: https://github.com/LeaVerou/blog/discussions/137#discussioncomment-16340589

Thanks :)

What mixin behavior feels most natural to you around nested rules? · LeaVerou blog · Discussion #137

🚨 Want mixins in CSS? Help the CSS WG by telling us what feels natural to you! Look at this code: @mixin --foo(--arg <length>) { @result { &, & > h2, & + p { width: var(--arg); } } } div { @apply -...

GitHub
@bramus having read your explanation, I am even more confused now. I am aware that without @ property the var passed is not a length, but I didn't know that 'length' forces value computation. From a code point of view, choosing an em unit I am describing "this should be in relation to the current font-size". em is a length. Why should that mean that the characteristics of the unit are getting nullified? even if it is computed, at the point of computation, it should still ... @leaverou having
@bramus ... consider the font-size. Should it not? What happens when I pass container units? Will they also ignore their relation to a container? @leaverou

@nachtfunke @leaverou Because the function says `--arg` should be a `<length>`, it will compute the value (similar to registered custom props). So where you `@apply` the mixin, it will take the CQ units from that element.

(If you don’t want that: don’t type the `--arg`. It’s a simple as that.)

@leaverou oof that is really difficult to understand, all of it. I’d expect the width to be 10em, not computed pixels. Do I misunderstand this? Apply will transform relative values?
@leaverou What am I missing to potentially mean that `p` would have no width?
@mez Sorry, I meant no width declaration is applied to it, i.e. it just gets the default width.
@leaverou Right, but is the possibility of that only there because it's `+` and not `>`? How could it not have a width decoration but the `h2` would?
@mez The question is asking which outcome feels most natural *to you*. If it seems weird for no width declaration to apply in that case, then don't pick these answers! 😀

@leaverou Cool, that's good enough. Just wanted to make sure I wasn't forgetting some "normal" case of cascade etc to inform that.

fwiw, I voted B, but A would be understandable. Dropping the cascade for mixins would be a little weird, but just another exception/oddity to remember 😅

@mez @leaverou I had the exact same thought process, "what why would it be different in the last case??, hmm okay maybe I'm missing something, but B seems right... Or maybe A 🤔" voted B too.
@leaverou Should the image show "width: 100px", "width: 200px", "width: 300px" instead of "font-size: 10px", "font-size: 20px", and "font-size: 30px"? The image has no 100/200/300 in it…
@gumnos No, it shouldn't. The width is injected via the mixin (which is used via @-apply
@leaverou 10em is passed to the mixin if i read the screenshot correctly, so the Answer would be 10em (for all, hopefully), not 100px. Or what are my old eyes missing?
@seiz ems are relative units, they need to eventually resolve to an absolute unit

@leaverou To me, it should be equivalent of replacing the `@apply` line with the content of `@Result` (using the value passed as the argument), that's all. Just like SASS. So option B feels the most natural to me.

https://sass-lang.com/playground/#eJwzNHTIzazIzFNIy8/XUEksStdUqOZSAAI1HQU1BTuFDCMQra1QABVWUCjPTCnJsFIAqbUGC9Vy1XJxpWSWgVU4ZOYl55SmpILNMzRIzdUEKUrLzyvRLc6sSrVSMDQoqLAG6gBpABkP1oUkb4QkD7MWSdoYIg0ATdkyNg==

@leaverou @SteveRudolfi @csswg Since em represents the font size of the current element, answer B is the only one that makes sense to me. It would be weird if em just works differently when used in combination with a mixin.