csstools / postcss-nesting

Nest style rules inside each other

Home Page:https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple @nest in combined selector don't transform

daanvosdewael opened this issue · comments

Input:

.a {
    display: flex;

    @nest .foo &,
    @nest .bar & {
        color: #fff;
    }
}

Output:

.a {
    display: flex;
}

.foo .a,
@nest .bar .a {
    color: #fff;
}

Expected:

.a {
    display: flex;
}

.foo .a,
.bar .a {
    color: #fff;
}

The second @nest is not transformed. This issue is different than #40 because the @nest selectors are combined with a comma.

Versions:

  • postcss: 7.0.6
  • postcss-nesting: 7.0.0

Hello, the issue you are experiencing is due to syntax. @nest is not repeated between selectors. What you want to write is:

.a {
    display: flex;

    @nest .foo &, .bar & {
        color: #fff;
    }
}

Thanks for your reply. Indeed the issue is fixed when I use that syntax.

I must say that I'm not used to have multiple selectors on one line. Please consider adding some @nest examples in the documentation.

I do still have an issue with the @nest rule. Consider the following:

Input:

.a {
    display: flex;

    &.b &,                  /* <-- added this line */
    @nest .foo &, .bar & {
        color: #fff;
    }
}

Output:

.a {
    display: flex;

    &.b &,
    @nest .foo &, .bar & {
        color: #fff;
    }
}

Expected:

.a {
    display: flex;
}

.a.b,
.foo .a,
.bar .a {
    color: #fff;
}

I know it's an edge case, but would it be possible to make this work? I'm currently working on a codebase where I don't have control over the HTML, so I have to get creative with the selectors ;)

Nesting selectors do not concatenate like strings, as they can in Sass.

For example, & > & where & is .foo does not equal .foo > .foo, nor does &_bar equal .foo_bar.

Instead, & represents the parent element. It matches it like a node in JavaScript. So, you cannnot match & & because that is like looking for something that is a child of itself. Similarly, something like &_bar would try to match an element that is also a _bar tag.

Ahh shoot, I gave you a wrong example. (What you just said makes total sense btw)

Apologies, one more time. &.b instead of &.b &:

.a {
    display: flex;

    &.b,
    @nest .foo &, .bar & {
        color: #fff;
    }
}

Nesting selector lists either begin with @nest or &. The only reason & works is because it comes first and only once, so it safely implies @nest beforehand. This is due to how CSS parsers in browsers work, and how they avoid something called “look ahead” for speed.

So, in your example, you’ll want to put @nest before your selector list.