Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sass Ampersand to add Tag to Class

Tags:

css

sass

I have some Sass like this:

.zbounce1, .zbounce2, .zbounce3, .zbounce4
    animation-name: bounceIn
    animation-duration: .5s
    animation-timing-function: ease-in-out

span.zbounce1, span.zbounce2, span.zbounce3, span.zbounce4
    display: inline-block

I would like to simplyfy the second part to a nested bit of the first part, so I don't have to mention every class again:

    span.&
        display: inline-block

Sadly, this is not legal. (The other way round, specializing a bunch of styles with a nested &.anotherClass is easy...

Any workaround to achieve this? (perhaps with the @extendOnly-Placeholder?) or some funky sass concatenation...?

like image 951
Frank Nocke Avatar asked Nov 21 '17 16:11

Frank Nocke


People also ask

What does ampersand do in Sass?

In Sass, the ampersand( & ) is like a variable that always represents the parent selector. Paired with nesting, the ampersand allows us to do a lot of helpful things from super simple to when-would-I-ever-actually-do-this complex.

What does the & mean in SCSS?

The & is a special selector invented by SCSS which is used in nested selectors to refer to the outer selector . It simply means that it will be replaced with the outer selector when compiling to CSS. There are some most commonly used cases: there is a space after the ampersand.

Can you use ampersand in CSS?

Modifying the ampersand Even though you can't have two ampersands touching without the interpolation brackets — as we demoed earlier in our pseudo class example — you can have another selector touch the ampersand. Touching the ampersand works well with modifier classes.


2 Answers

You can achieve this in native sass, it's just a bit convoluted. You need to use selector-append to add the span to all of the selectors, and @at-root to do so at root level (if that makes sense? it's hard to even explain). Basically it looks like this:

.zbounce1, .zbounce2, .zbounce3, .zbounce4 {
  animation-name: bounceIn;
  animation-duration: .5s;
  animation-timing-function: ease-in-out;
  @at-root #{selector-append(span, &)} {
    display: inline-block;
  }
}

Which should output this result:

.zbounce1, .zbounce2, .zbounce3, .zbounce4 {
  animation-name: bounceIn;
  animation-duration: .5s;
  animation-timing-function: ease-in-out;
}
span.zbounce1, span.zbounce2, span.zbounce3, span.zbounce4 {
  display: inline-block;
}

Here's a Codepen example (you'll have to view source and look for the style block in the header to see the output, I'm not sure how else to demonstrate it but hopefully this helps!)

like image 189
delinear Avatar answered Oct 23 '22 22:10

delinear


Ladies and gentlemen...

.zbounce, .zbounce1, .zbounce2, .zbounce3, .zbounce4, .zbounce5
    ...
    @at-root #{selector-append(span, &)}
        display: inline-block

getting me, what I want:

span.zbounce, span.zbounce1, span.zbounce2, 
span.zbounce3, span.zbounce4, span.zbounce5 { 
    display: inline-block;
}

Thanks to @ovokuro for pointing me into the – right – direction!

like image 41
Frank Nocke Avatar answered Oct 23 '22 22:10

Frank Nocke