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.
Спасибо.
Ответы
Ответ 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
}
}
}