sass: Passing arguments from a mixin to a content block
Mixin content is great and has done wonders for code implementing wrapper and context abstractions. However, there is often some setup done in the mixin and that setup needs to be available to the content when it is included. The current strategy is to use global variables, which works, but is obviously not ideal.
I’d like to introduce a way for mixins to include their content block and to pass arguments to the content.
Calling the content with arguments
In order to pass arguments to content blocks an argument list can be passed to the content directive. This accepts positional and keyword arguments for passing to a content block. Variable argument semantics are allowed.
@mixin accepts-content {
@for $i from 1 to 5 {
@content ($i, 360deg * $i / 5);
}
}
Receiving arguments within a content block
A content block receives arguments using a new directive called @receive
. The directive allows an argument list declaration that is the same as for functions and mixins. Positional arguments, default values, and variable arguments are all allowed.
@include accepts-content {
@receive ($number, $hue);
.color-#{$number} {
background-color: hsl($hue, 75%, 90%);
}
}
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Reactions: 79
- Comments: 123 (19 by maintainers)
Commits related to this issue
- Add specs for @content arguments See sass/sass#871 — committed to sass/sass-spec by nex3 6 years ago
- Add specs for @content arguments (#1299) See sass/sass#871 — committed to sass/sass-spec by nex3 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
- Implement passing arguments to @content See sass/sass#871 Spec https://github.com/sass/sass-spec/pull/1313 Fixes #2723 — committed to sass/libsass by xzyfer 6 years ago
Please, stop
+1
ing in comments, use thumb up on already posted comments instead or provide meaningful comments, otherwise devs will definitely lock down this issue and we won’t be able to comment it and make new proposals any further.I think there are little chances we’ll see any new features untill Dart version of Sass will be completely finished.
I’ve written up a proposal for this feature. I’ll leave it open for comments for two weeks, then mark it accepted if nothing has come up.
How long would this typically take to trickle into node-sass? Its just what I need!
This has also landed in LibSass. Should this issue be closed?
You are completely correct.
Loaded statements like mine are completely uncalled for.
I shouldn’t let my bad mood influence my words.
I apologise for that. I should not have said it.
I wish to say that I very much appreciate the work you do, and the contributions you have made to the open source community. What you do does not deserve words like that.
I’ve marked the proposal as accepted, and plan to start implementing it immediately.
@xzyfer When you close out these issues, can you let me know the first LibSass release number these features are expected to land in? That way I can update the new reference docs’ implementation tracker.
@trev-dev This issue is about passing arguments not to mixin, but from mixin to its content block (which can be invoked multiple times with different args).
For those who wonders is it possible at least anyhow to pass argument from mixin to
@content
— yes, it is possible.You would need to use temp variable and
!global
flag. Though, it is a hacky way, and not that pretty, it will do the job.I wanted some better API to work with that temp variable, so I created few mixins and function to cover that case better till we’ll have native solution.
You can check example from Ekzo here:
I created a small example of how to use this feature to simplify the theme generation. https://gist.github.com/tzi/2e54c245af91769ea912fa4e5f6d3820
Really like this idea and sad to see after over 2 years it is still unimplemented.
+1 for:
This feature would be immensely useful for modular CSS architecture.
Node Sass versions are released later (sometimes substantially later) than the corresponding LibSass versions. I’m not sure if there’s a central place to look for them. Maybe @xzyfer or @nschonni would know?
Alternately, you could use Dart Sass (https://www.npmjs.com/package/sass) which definitely has this feature.
And the subsequent node-sass release if anyone catches it. Then we can put this whole 5+ year ordeal to bed 👯 🍾
Yeah and node-sass still isn’t using it.
Dang, too bad I already moved to css-in-js. This would have been super neat to play with.
Woww i lived to see this
Comments of general distaste are not very useful without explanations and, ideally, alternative suggestions.
It’s happening…!
I like this discussion a lot! But I needed it before it lands in v4 – so I came up with a workaround to do stuff like that;
results in
If someone is interested in the workaround you can find it here: https://github.com/signalwerk/scontecss
You can give a mixin optional args already. This kind of feels redundant to me?
The part I’m not a fan of is how much additional code this adds from a reuse standpoint. Using global variables is worse when it comes to authoring the mixins, but more convenient for using them. Shorter is better. If it must be a keyword,
@receive
or@args
is better than@receive-content
or@content-arguments
, even though they may be better descriptors.Borrowing a bit from Haskell here:
Using a Ruby style syntax as @hcatlin suggests would also be acceptable.
I think I like @content-arguments best so far.
Goes to show, good things come to those who wait.
Nice work guys!
Woohoo! Been on the lookout for this for 3 years! Big thanks!
Nice work, @signalwerk
Big frickin +1
@davebeesley, try the
!global
flag.How about
@include foo(red, blue) using ($a, $b, $c)
?Hrrm… as I look at the use case more, this seems like something we think would be pretty regularly used. Aka, I could make a Sass library that uses this as a common API for interaction. And, with that in mind, this overall approach of making it a directive line is odd to me. I’d much rather it somehow work into the syntax more directly.
We could steal some Ruby syntax!
On Sun, Aug 4, 2013 at 11:30 AM, Chris Eppstein notifications@github.comwrote:
I guess I’m not a fan of receive due to it being commonly misspelled. Just brainstorming…
@take @pass @get @-> @vars @name
On Friday, August 2, 2013, Nathan Weizenbaum wrote: