Ampersand (Parent Selector) Inside Nested Selectors

Sass Ampersand nesting with pseudo selectors

This is because the ampersand is just concatenating the parent with the child. If you want the compiled CSS to look like your example you need to do this:

.test {
&:first-child &-image{
display: block;
}
}

sass merge selectors on ampersand

There is no way that I know to merge selectors as requested.

As you're not allowed to change the parent selector, the only solution I see would be to use the @at-root rule.

@at-root

The @at-root rule is usually written @at-root { ... } and causes everything within it to be emitted at the root of the document instead of using the normal nesting. It's most often used when doing advanced nesting with the SassScript parent selector and selector functions.

Definition on sass-lang.


Here is an example:

[dir] .foo {
$root: '.foo';

background-image: linear-gradient(black, white);

@at-root {
[dir=ltr] #{$root} {
padding-right: 1em;
}

[dir=rtl] #{$root} {
padding-left: 1em;
}
}
}

This will compile to:

[dir] .foo {
background-image: linear-gradient(black, white);
}
[dir=ltr] .foo {
padding-right: 1em;
}

[dir=rtl] .foo {
padding-right: 1em;
}

You could create a mixin to help you with that:

@mixin dir($dir: ltr, $selector: &) {
@at-root {
[dir=#{$dir}] #{$selector} {
@content;
}
}
}

[dir] .foo {
$root: '.foo';
background-image: linear-gradient(black, white);

@include dir(ltr, $root) {
padding-right: 1em;
}

@include dir(rtl, $root) {
padding-right: 1em;
}
}


Food for thougt

If you don't have to support internet explorer, you might want to check padding-inline-end and padding-inline-start properties.

They will free you from the need to have different rules for different directions.

padding-inline-end

The padding-inline-end CSS property defines the logical inline end padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.

MDN Docs - padding-inline-end

padding-inline-start

The padding-inline-start CSS property defines the logical inline start padding of an element, which maps to a physical padding depending on the element's writing mode, directionality, and text orientation.

MDN Docs - padding-inline-start

Target immediate parent with ampersand (SCSS)

This is an expected behavior, according to Referencing Parent Selectors: &

I would not recommend using this technique, because it's counter intuitive.

LESS - what is the purpose of & AFTER a nested selector

The article "LESS CSS: Secrets of the Ampersand" details the difference well. I'll highlight the key uses:

  • Attach a class to an existing selector
  • Change state based on parent classes
  • Filter a nested selector to only match certain elements
  • Avoid repetition when selecting repeated elements
  • Simplify combinatorial explosions

The latter is my favorite. I've used it to handle some crazy IE issues. Check this out:

/**
* Add a top border to paragraphs,
* but remove that border when a preceding paragraph already has one.
*/
p {
border-top: 1px solid gray;
& + & {
border-top: 0;
}
}

I think if you can wrap your mind around what this usage of & does, all the other uses become obvious.



Related Topics



Leave a reply



Submit