sass/sass

Make sure that an ampersand in @content is not placed before class

Closed this issue · 2 comments

I have a mixin that is being used for creating breakpoints and where the class body:not(.responsive-testing) always needs to be placed first.

So the ideal structure would be: body:not(.responsive-testing) .test-class

But sometimes inside @content, there is an ampersand being used so then it will render it like this: .test-class body:not(.responsive-testing)

This is the code of the mixin, i'm using dart-sass

@mixin tablet {
  @include susy-breakpoint($tablet-width, $susy-tablet) {
    body:not(.responsive-testing) &{
      @content;
    }
  }

  @container (min-width: #{$tablet-width}) {
    body.responsive-testing & {
      @content;
    }
  }
}

An example using the mixin that generates this example:

  @include tablet {
      flex-basis: 33%;
      .test-class & {
        flex-basis: 50%;
        background: blue;
      }
    }

I've created a codepen so you can check by yourself while compiling the css in the pen.

https://codepen.io/indymeermans/pen/MWxgQvX

nex3 commented

Fundamentally, the innermost style rule (in this case, .test-class &) has final say about what the selector looks like. So if it says "put .test-class outside everything else", then that's what happens. You can avoid doing this by using Sass's built-in selector functions to implement your own, more complex nesting behavior. In this example, I've implemented a before-everything-but-body() mixin that will nest a selector within the outermost parent selector if it has a body tag but outside everything else.

@nex3 Thanks for leading me in the right direction! I'm going to try implement this inside the mixin only. Otherwise it would take me a long time to adjust it and implement @include before-everything-but-body inside every file and project.

EDIT: i figured out that its impossible to see whats inside @content; so I guess i have to adjust everything