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
Force Ckeditor to Add a Class to P-Tags
How Does CSS Computation for Background Percentages Work
Which CSS Selector Can Be Used to Select a Flex Box Item in Wrapped State
Apply a CSS Filter Only on Background
CSS Pseudo-Element to Apply the First Character of an Element
How to Make a Curve on a Rectangle's Top in CSS? Only in Top Edge
Limit the Width of a Column to the Width of a Particular Grid Item
Use Calc() Function in Makestyles
Continuously Adjust Element Size as Screen Size Changes
How to Override a Less Mixin Variable Based on a Parent's Variable
Offset Border Effect in Pure CSS
Webkit Text Aliasing Gets Weird During CSS3 Animations
Specifying External Font in Javafx CSS
How to Color Specific Cells in a Data Frame/Table in R
How to Set a Specific CSS Class to a Widget in Gtk3? (C)