Reputation: 3767
I want to create a variable with classes like so
$multi: foo, bar, baz
And I want to created a combined selector like so:
.foo, .bar, .baz {}
I am used the indented syntax (don't know if that would matter). The reason I want the combined selector generated from the variable: I need to do calculations based on how many classes are defined there. Please don't give a suggestion like (use extends!) because that will require me to make another class. I need to be able to get close or exactly to the regular combined selector output.
Upvotes: 5
Views: 3593
Reputation: 5404
I had the same issue as the OP, and this was the first search result I found, so now that I’ve figured it out, I’ll post my solution, even though the question is 1.5 years old.
Here’s what I found out: in order to use a variable as a selector, you use SASS interpolation, which works perfectly with comma-separated strings. However, if you want the variable that holds your selectors to be a list
(so that you can use list functions on it, e.g. length($multi)
), the interpolation will generate a malformed selector.
So, the simple solution is to first define your variable as a list, then when you need to use it as a selector, convert that list into a comma-separated string:
$multi: ".foo", ".bar", ".baz"
$multi-selector: ""
@each $selector in $multi
@if $multi-selector != ""
$multi-selector: $multi-selector + ", "
$multi-selector: $multi-selector + $selector
#{$multi-selector}
//CSS properties go here
You may want to abstract the list-to-comma-separated-string functionality into a function (note: SASS’s join
function doesn’t do this; it joins two lists into a new one). Here’s one possible implementation:
@function unite($list, $glue: ", ")
@if length($list) == 1
@return $list
$string: ""
@each $item in $list
@if $string != ""
$string: $string + $glue
$string: $string + $item
@return $string
At which point the original code can be as concise as:
$multi: ".foo", ".bar", ".baz"
#{unite($multi)}
//CSS properties go here
Upvotes: 4
Reputation: 366
(code from previous answer) Cool function! Usefull. I just wanted to add some SCSS syntax, to give an opportunity to people to use it:
@function unite($list, $glue: ", ") {
@if length($list) == 1 {
@return $list;
} @else {
$string: "";
@each $item in $list {
@if $string != "" { $string: $string + $glue; }
$string: $string + $item;
}
@return $string;
}
}
At which point the original code can be as concise as:
$multi: ".foo", ".bar", ".baz"
#{unite($multi)}
//CSS properties go here
Upvotes: 1
Reputation: 9325
Compass offers a built-in sprite mixin that does just this. If you don't want to use all of Compass, you could look into their source to see how they are doing it.
Upvotes: 0