Alessandro_Russo
Alessandro_Russo

Reputation: 2191

How to solve SassError: Invalid parent selector "*"?

I have an Angular 9 app and when I use this snippet SCSS it returns this error:

SassError: Invalid parent selector "*"
   ╷
52 │         &#{$value} {
   │         ^^^^^^^^^^^^^^^
   ╵

This is the snippet:

$values: (
  "":"",
  one: one,
  two: two,
);

@mixin gen() {
  @each $value, $key in $values {
    @media (min-width: 300px) {
      &#{$value} {
        @content
      }
    }
  }
}

@mixin display {
  display: block;
}

.display > * {
  @include gen() {
    @include display();
  }
}

I want in output classes for each value like: display > *, display-one > *, display-two > *and so on.

Upvotes: 0

Views: 4185

Answers (2)

Jakob E
Jakob E

Reputation: 4926

What @Yosef describes is correct – however, there are a few things to consider

When using @each loops on maps the order is $key, $value.

To minimize the CSS output move the @each loop inside the media query – like:

@media (min-width: 300px) {
  //  move loop here
  @each $key, $value in $values {
    ...
  }
}


// CSS output without redundant media queries
@media (min-width: 300px) {
  .display > * {
    display: block;
  }
  .display-one > * {
    display: block;
  }
  .display-two > * {
    display: block;
  }
} 

Last but not least consider not doing this at all – use an attribute selector instead – this way you can handle everything in one selector :-)

@media (min-width: 300px) {
  [class|=display] > * { display: block; }
}

// This will match 
.display > *, .display-one > *, .display-two > *, .display-xxx > * etc.

Upvotes: 1

Yosef Tukachinsky
Yosef Tukachinsky

Reputation: 5895

1. You want to select * after the value >, means you should add it in the mixin

2. You want select -#{$value} and not just &#{$value}. So A- you have to add the -, and B- for $value="" the - is not exist. so probably you should give it special attention.

Shortly, change the scss to

$values: (
        one: one,
        two: two,
);

@mixin gen() {
  @media (min-width: 300px) {
    > * {
      @content
    }
  }
  @each $value, $key in $values {
    @media (min-width: 300px) {
      &-#{$value} > * {
        @content
      }
    }
  }
}

@mixin display {
  display: block;
}

.display {
  @include gen() {
    @include display();
  }
}

Output:

@media (min-width: 300px) {
  .display > * {
    display: block;
  }
}
@media (min-width: 300px) {
  .display-one > * {
    display: block;
  }
}
@media (min-width: 300px) {
  .display-two > * {
    display: block;
  }
}

Upvotes: 2

Related Questions