sass

How to prepend a nested class with a selector in SCSS?


I have the following SCSS:

.parent-class {
  .class {
    background: lightgreen;

    img &-img{
      border: blue;
    }
  }  
}

...which produces this:

.parent-class .class {
  background: lightgreen;
}
img .parent-class .class-img {
  border: blue;
}

I'm trying to pre-pend the .class-img with the img selector and have my result be this img.class-img:

.parent-class .class {
  background: lightgreen;
}
.parent-class img.class-img {
  border: blue;
}

Solution

  • I'm not sure I'd advocate for doing this but it is possible.

    SCSS has an @at-root directive which allows you to output the content of the block at the root level. You can combine that with the selector.unify() function to build the selector you need.

    The example given in the @at-root docs includes a unify-parent mixin which is particularly helpful in your case.

    @use "sass:selector";
    
    // Mixin optional - see below
    @mixin unify-parent($child) {
      @at-root #{selector.unify(&, $child)} {
        @content;
      }
    }
    
    .parent-class {
      .class {
        background: lightgreen;
        
        // With the mixin
        @include unify-parent("img") {
          &-img {
            border:blue;
          }
        }
    
        // Without the mixin (be sure to keep @use though)
        @at-root #{selector.unify(&, img)}-img {
            border: blue;
        }
      }  
    }
    

    https://sass-lang.com/documentation/at-rules/at-root