Use trailing ampersand (&) as a class combination selector, not a descendant selector

4.1k views Asked by At

I want to apply a class .highlight to a bunch of different elements and style them according to the element type. I could do this:

input[type="text"].highlight {...}
select.highlight {...}
someOtherSelector.hightlight {...}

But I'm trying to use the trailing ampersand (&) to make my code more succinct.

I've tried the following:

.highlight {

    input[type="text"].& {
        border: 1px solid $brand-purple;
    }
}

But I get the following error:

Error: property "input" must be followed by a ':'

I've also tried:

.highlight {

    input[type="text"]& {
        border: 1px solid $brand-purple;
    }
}

But I get the following error:

Invalid CSS after "[type="text"]": expected "{", was "&" "&" may only be used at the beginning of a compound selector.

Is there a way around this, or can this just not be done in SASS?

2

There are 2 answers

6
Saurav Rastogi On BEST ANSWER

Use #{&} instead of just .&. And use @at-root which allows you to break out of your nesting structure entirely to the "root" of your nesting tree.

Write this in SASS:

.highlight {

  @at-root input[type="text"]#{&} {
      border: 1px solid $brand-purple;
  }
}

This will complied in CSS to:

input[type="text"].highlight {
  border: 1px solid purple;
}

Hope this helps!

3
Marko Manojlovic On

You need to reorganize your scss a bit, what you need is:

input[type="text"]  {
  &.highlight {
    border: 1px solid $brand-purple;
  }
}

*Edit after your update, you can use @at-root:

.highlight {
  @at-root {
    input[type="text"]  {
      &.highlight {
        border: 1px solid $brand-purple;
      }
    }
  }
}