Подтвердить что ты не робот

Sass css: целевой родительский класс из дочернего

Я использую sass и нашел проблему. Это пример того, что я пытаюсь сделать:

.message-error {
    background-color: red;

    p& {
        background-color: yellow
     }
  }

Ожидаемый css:

.message-error {
    background-color: red;
}
p.message-error {
    background-color: yellow ;
}

Идея: все элементы с ошибкой .message будут красными, за исключением случаев, когда это p.message-error. Это не реальная ситуация, просто чтобы показать пример.

SASS не может скомпилировать это, я даже попробовал конкатенацию строк. Есть ли какой-нибудь плагин, который будет делать то же самое?

Примечание: Я знаю, что могу добавить другое определение css, например

p.message-error{....}

но я хотел бы избежать этого и использовать одно место для всех определений ошибок .message.

Спасибо.

4b9b3361

Ответ 1

Как и в случае с Sass 3.4, это теперь поддерживается. Синтаксис выглядит следующим образом:

.message-error {
    background-color: red;

    @at-root p#{&} {
        background-color: yellow
    }
}

Обратите внимание на директиву @at-root и синтаксис интерполяции на амперсанде. Невозможность включить директиву @at-root приведет к выбору селектора типа .message-error p.message-error, а не p.message-error.

Ответ 2

Натали Вейзенбаум (ведущий разработчик и разработчик Sass) говорит, что он никогда не будет поддерживаться:

В настоящее время & синтаксически совпадает с селектором элементов, поэтому он не может появиться рядом с ним. Я думаю, что это помогает уточнить, где это может быть используемый; например, foo&bar никогда не будет действительным селектором (или возможно, эквивалентен foo& bar или foo &bar). Я не думаю, что это использование дело достаточно сильное, чтобы гарантировать его изменение.

Источник: # 282 - Селектор Element.parent

Насколько мне известно, нет возможного обходного пути.

Ответ 3

Лучше всего было бы, вероятно, это сделать (предполагая, что у вас есть немного больше в классе .message-error, чем просто цвет фона.

.message-error {
  background-color: red;
}

p.message-error {
  @extend .message-error;
  background-color: yellow
}

Этот подход не предлагает такую ​​близкую группировку, но вы можете просто держать их близко друг к другу.

Ответ 4

Я думаю, что если вы хотите, чтобы они были сгруппированы родительским селектором, вам может потребоваться добавить общий родительский элемент:

body {
    & .message-error {background-color: red;}
    & p.message-error {background-color: yellow}
}

Конечно, body может быть заменен другим другим родителем, например #Content или другим div именем, которое будет содержать все сообщения об ошибках.

ОБНОВЛЕНИЕ (другая идея)

Если вы используете @для и списки, то это похоже, что это должно работать (я точно не знаю, будет ли список разрешать . (период).

@for $i from 1 to 3 {
  nth(. p. ul., #{$i})message-error {
    background-color: nth(red yellow cyan, #{$i}));
  }
}

Скомпилировать что-то вроде:

.message-error {
   background-color: red;}
p.message-error {
   background-color: yellow;}
ul.message-error {
   background-color: cyan;}

Ответ 5

@Zeljko Невозможно сделать то, что вы хотите, через SASS.

См. комментарий Nex3: https://github.com/nex3/sass/issues/286#issuecomment-7496412

Ключ - это пробел перед '&':

.message-error {
    background-color: red;

    p & {
        background-color: yellow
     }
  }

вместо:

.message-error {
    background-color: red;

    p& {
        background-color: yellow
     }
  }

Ответ 6

Я столкнулся с этим и раньше. Bootstrap 3 обрабатывает это с помощью взлома родительского селектора. Я немного изменил его в своих целях...

@mixin message-error() {
  $class: '.message-error';
  #{$class} {
    background-color: red;
  }
  p#{$class} {
    background-color: yellow;
  }
}
@include message-error();

wheresrhys использует аналогичный подход выше, но с некоторыми ошибками sass. Приведенный выше код позволяет вам управлять им как одним блоком и сворачивать его в вашем редакторе. Вложение переменной также делает ее локальной, поэтому вы можете повторно использовать класс $для всех экземпляров, где вам нужно применить этот хак. См. Ниже рабочий образец...

http://sassmeister.com/gist/318dce458a9eb3991b13

Ответ 7

Я сделал mixin, который решает эту проблему.

Github: https://github.com/imkremen/sass-parent-append

Пример: https://codepen.io/imkremen/pen/RMVBvq


Использование (scss):

.ancestor {
  display: inline-flex;

  .grandparent {
    padding: 32px;
    background-color: lightgreen;

    .parent {
      padding: 32px;
      background-color: blue;

      .elem {
        padding: 16px;
        background-color: white;

        @include parent-append(":focus", 3) {
          box-shadow: inset 0 0 0 8px aqua;
        }

        @include parent-append(":hover") {
          background-color: fuchsia;
        }

        @include parent-append("p", 0, true) {
          background-color: green;
        }
      }
    }
  }
}

Результат (css):

.ancestor {
  display: inline-flex;
}
.ancestor .grandparent {
  padding: 32px;
  background-color: lightgreen;
}
.ancestor .grandparent .parent {
  padding: 32px;
  background-color: blue;
}
.ancestor .grandparent .parent .elem {
  padding: 16px;
  background-color: white;
}
.ancestor:focus .grandparent .parent .elem {
  box-shadow: inset 0 0 0 8px aqua;
}
.ancestor .grandparent .parent:hover .elem {
  background-color: fuchsia;
}
.ancestor .grandparent .parent p.elem {
  background-color: green;
}

Ответ 8

Этот чит может работать

 {
     $and: .message-error;
     #{$and} {
        background-color: red;
     }

     p#{$and} {
        background-color: yellow
     }
  }

Возможно, вы даже сможете использовать $& в качестве имени переменной, но я не уверен на 100%, что он не выкинет ошибку.

И SASS имеет встроенную область обзора, которая устраняет необходимость беспокоиться о том, что значение $and просачивается в остальную часть вашей таблицы стилей

Переменные доступны только на уровне вложенных селекторов где они определены. Если они определены вне любых вложенных селектора, они доступны повсюду.

Ответ 9

В текущей версии: Selective Steve (3.4.14) теперь это возможно, просто нужно немного обновить код:

.message-error {
    background-color: red;
    p &{
        background-color: yellow
     }
 }

это работает только если вы один уровень вложен, например, он не работает, если у вас есть что-то вроде этого:

.messages{
    .message-error {
        background-color: red;
        p &{
            background-color: yellow
         }
     }
 }