简体   繁体   中英

Using a list of selectors in combination with & in a nested selector in Sass SCSS

In a Sass sheet I'm working on, I'd like to be able to store some body classes inside of a variable, and use them in a selector nested inside of a selector for some elements, like this:

$classes: ".bodyClass1, .bodyClass2";

.aClass, .anotherClass {
  /* some styles */
  #{$classes} & {
    /* Styles under $classes */
  }
  #{$classes} &:hover {
    /* Styles under $classes when hovering */
  }
}

The output I'm looking for is:

.aClass, .anotherClass {
  /* some styles */
}
.bodyClass1 .aClass, .bodyClass2 .aClass, .bodyClass1 .anotherClass, .bodyClass2 .anotherClass {
  /* Styles under $classes */
}
.bodyClass1 .aClass:hover, .bodyClass2 .aClass:hover, .bodyClass1 .anotherClass:hover, .bodyClass2 .anotherClass:hover {
  /* Styles under $classes when hovering */
}

But it renders as:

.aClass, .anotherClass {
  /* some styles */
}
.aClass .bodyClass1, .bodyClass2 .aClass, .anotherClass .bodyClass1, .bodyClass2 .anotherClass {
  /* Styles under $classes */
}
.aClass .bodyClass1, .bodyClass2 .aClass:hover, .anotherClass .bodyClass1, .bodyClass2 .anotherClass:hover {
  /* Styles under $classes when hovering */
}

I can fix this by creating separate variables with & , &:hover , &:active , etc. after the body classes instead, but I'm wondering if there's a way to use variables in the way I was trying to use them.

Edit:

srekoble's solution to use loops works perfectly for me! I adapted it into a function, here it is if anyone else might want to use it:

$classes: ".bodyClass1", ".bodyClass2";

@function c($classes, $append: null){
  $processedClasses: "";

  $length: length($classes);

  @for $i from 1 through $length {
    @if $append {
      $processedClasses: #{$processedClasses}#{nth($classes, $i)} #{$append}#{", "};
    } @else {
      $processedClasses:  #{$processedClasses}#{nth($classes, $i)}#{", "};
    }
  }

  @return $processedClasses;
}

.aClass, .anotherClass {
  /* some styles */

  #{c($classes, "&")} {
    /* Styles under $classes */
  }
  #{c($classes, "&:hover")} {
    /* Styles under $classes when hovering */
  }
}

Which outputs as:

.aClass, .anotherClass {
  /* some styles */
}
.bodyClass1 .aClass, .bodyClass2 .aClass, .bodyClass1 .anotherClass, .bodyClass2 .anotherClass {
  /* Styles under $classes */
}
.bodyClass1 .aClass:hover, .bodyClass2 .aClass:hover, .bodyClass1 .anotherClass:hover, .bodyClass2 .anotherClass:hover {
  /* Styles under $classes when hovering */
}

You could try something like this:

$classes: ".bodyClass1" , ".bodyClass2";

.aClass, .anotherClass {
  /* some styles */
  @for $i from 1 through 2 {
    #{nth($classes, $i)} & {
      /* Styles under $classes */
    }

    #{nth($classes, $i)} &:hover {
      /* Styles under $classes when hovering */
    }
  }
}

An example: http://sassmeister.com/gist/acb0096e9d35e1ae437d

This would be another approach which is in my opinion more scalable. Because you don't have to edit the numbers in your for loop each time you update the variable.

$classes: (bodyClass1, bodyClass2);

@each $class in $classes {
  .aClass, .anotherClass {
    // your styles
    .#{$class} & {
      // your styles
      &:hover { 
         // your styles
      }
    }
  }
}

On SassMeister http://sassmeister.com/gist/6edf0319bd4d8462fa95

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM