Sass BEM: избегайте дублирования модификатора, когда элемент находится внутри модификатора
можно ли как-то отрефакторить следующий фрагмент кода, чтобы избавиться от объявление двойного модификатора?
.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
}
&--modifier & {
&__element {
rule: value;
}
}
}
выход хотел:
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
4 ответов
вложенность элементов внутри модификаторов-это известная проблема. Есть много обходных путей.
переменной способом
сохраните элемент блока в переменной.
и используйте его интерполированным при создании элемента внутри модификатора.
.block {
$block: &;
&__element {
property: value;
}
&--modifier {
property: value;
#{$block}__element {
property: value;
}
}
}
см. Вывод ниже.
функции как
1. Создайте функцию, возвращающую элемент block.
он получит родителя селектор и вырезать слово перед --
(это блок). Выглядит банально, но это самый простой способ.
@function block() {
$selector: str-slice(inspect(&), 2, -2);
$index: str-index($selector, '--') - 1;
@return str-slice($selector, 0, $index);
}
2. Использовать функцию интерполяции.
который вернет имя блока, чтобы вам не пришлось его повторять.
.block {
property: value;
&--modifier {
property: value;
#{block()}__element {
property: value;
}
}
}
см. Вывод ниже.
оба способа выведут на:
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
вы можете поместить блок в &--modifier
селектор, как это, используя имя класса блока, а не &
таргетинг.
.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
.block {
&__element {
rule: value;
}
}
}
}
однако это, возможно, не лучшее решение BEM, вы должны рассмотреть переименование вложенного блока в качестве элемента содержащего блока, такого как .block__another-element
или создание нового блока полностью.
вы могли бы добавить &
рядом с модификатором для решения, подобного решению Тони.
.block {
&__element {
rule: value;
}
&--modifier & {
rule: value;
&__element {
rule: value;
}
}
}
это, однако, потребует .block
быть корневым селектором, а не вложенным в любой другой селектор.
еще одно возможное решение. Однако в большинстве ситуаций я все равно предпочел бы решение Тони.
если кто-то использует меньше, это поможет вам!
@block:.parent;
@{block}{
backgroung:red;
&--modifier{
backgroung:blue;
}
&__child{
font-size:20px;
@{block}--modifier & {
font-size:40px;
}
}
}