Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sass: Multiple class selector from a variable

Tags:

css

sass

haml

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.

like image 614
Rey Avatar asked Jan 31 '12 16:01

Rey


People also ask

What is interpolation in sass?

Interpolation is basically an insertion. Interpolation allows us to interpolate sass expressions into a simple SASS or CSS code. Means, you can define ( some part or the whole ) selector name, property name, CSS at-rules, quoted or unquoted strings etc, as a variable.

How do I nest a class in sass?

The first way to nest in SCSS is very simple. Nest a number of HTML elements within a single HTML element. Then in your SCSS simple write the parent selector class name as you would in CSS, then write the nested tags within the parent. Bitchin, you are nesting in SCSS!


1 Answers

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
like image 70
Andrew Patton Avatar answered Sep 23 '22 05:09

Andrew Patton