I wrote two Sass mixins for adding a top margin to elements that are not the first visible child of their parent:
@mixin not-first-child {
:not(.visually-hidden, .hidden) ~ & {
@content;
}
}
@mixin margin-top($spacing: $paragraph-spacing) {
--margin-top-spacing: #{$spacing};
margin-bottom: 0;
@include not-first-child {
margin-top: var(--margin-top-spacing);
}
}
So this SCSS:
.foo {
@include margin-top(1rem);
}
will be transformed to this CSS:
:not(.visually-hidden, .hidden) ~ .foo {
--margin-top-spacing: 1rem;
margin-bottom: 0;
margin-top: var(--margin-top-spacing);
}
But this approach cannot be used in nested selectors.
.foo {
// some styles for .foo
.bar {
@include margin-top(1rem);
}
}
I would expect this to convert to
.foo :not(.visually-hidden, .hidden) ~ .bar {
--margin-top-spacing: 1rem;
margin-bottom: 0;
margin-top: var(--margin-top-spacing);
}
but instead I get this:
:not(.visually-hidden, .hidden) ~ .foo .bar {
--margin-top-spacing: 1rem;
margin-bottom: 0;
margin-top: var(--margin-top-spacing);
}
which is not what I want to achieve.
I read this article about advanced nesting and tried to rewrite the first mixin:
@mixin not-first-child {
@at-root #{selector.nest(':not(.visually-hidden, .hidden) ~', &)} {
@content;
}
}
but this didn’t make a difference. I also tried various other selector functions, but without success.