SCSS. Ссылка на второй уровень по возрастанию

Одним из методов организации классов в области предотвращения столкновений является расширение родительского класса + добавление некоторого суффикса. Например:

<div class="a">
  <div class="a__b">
  <div class="a__c">
    <span class="a__d">

Из соображений не дублирующего кода в файлах sass/scss можно ссылаться на родителя с помощью амперсанда - &, поэтому над структурой может быть достигнуто следующим образом:

.a{
 &__b{}
 &__c{}
 &__d{}

Что преобразуется в:

.a__b {}
.a__c {}
.a__d {}

Но возникают трудности, когда нужно получить такой css как результат:

.a:hover{
  color: red;  
}
.a:hover .a__b{
  color: blue;
}

Поскольку основная идея заключается не в дублировании селекторов, возникает вопрос - существует ли способ ссылки на родителя второго уровня? Я знаю, что && не проблема, но есть ли способ имитировать поведение с двойным амперсандом?

.a{
    &:hover{
        color: red;
        & __b { /* & -> .a:hover, but I need just .a */
            color: blue;
        }
    }

}

Не проблема, .a дублируется:

.a:hover { //here
  color: red;
  .a__b { //here
    color: blue;
  }
}

Также не проблема:

.a { //ok
  &:hover {
  color: red;

    .a__b { //oops, duplicated selector
      color: blue;
    }
  }
}

Итак, из соображений избежания столкновений много раз классы имеют длинные имена. И именно тогда дублированные селектора делают код очень страшным. Представьте себе, что вместо селектора .a будет: .custom-layers-list-panel-conatiner. Еще одна причина избежать дублирования классов заключается в том, что если родительский класс изменен, он должен быть изменен повсюду. Да, в настоящее время это довольно тривиальная задача с некоторыми конкретными инструментами, но она по-прежнему остается местом, где могут появляться ошибки.

Ответ 1

Обновление: лучше оригинала

.a{
  $grandparent: &;

  &:hover{
        color: red;
    & #{$grandparent}__b {
          color: blue;
        }
  }
}

и Оригинал:

@function r-pseudo($s) {
  $string: nth(nth($s, 1), 1);
    @return str-slice($string, 0, str-index($string, ':') - 1);
}

.a{
  &:hover{
        color: red;
    & #{r-pseudo(&)}__b {
          color: blue;
        }
  }
}

оба генерируют

.a:hover {
  color: red;
}
.a:hover .a__b {
  color: blue;
}

Ответ 2

Ваша идея была правильной, но вы должны поместить a: hover на верхний уровень, чтобы получить желаемый результат. Это не то, что вы хотели, но единственный способ, которым SCSS даст вам ваш целевой результат.

Я думаю, вы ищете это:

.a:hover {
  color: red;
  .a__b {
    color: blue;
  }
}

Вторая попытка, вроде этого?

.a {
  &:hover {
  color: red;

    .a__b {
      color: blue;
    }

  }
}