Sass BEM:当元素位于修改器内时,避免修改器重复

Sass BEM:当元素位于修改器内时,避免修改器重复,sass,bem,Sass,Bem,我是否可以通过某种方式重构以下代码段以摆脱双修饰符声明 .block { &__element { rule: value; } &--modifier { rule: value; } &--modifier & { &__element { rule: value; } } } 需要输出: .block { property: value; } .block--modifier

我是否可以通过某种方式重构以下代码段以摆脱双修饰符声明

.block {
  &__element {
    rule: value;
  }
  &--modifier {
    rule: value;
  }
  &--modifier & {
    &__element {
      rule: 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解决方案,您应该考虑将嵌套块重命名为包含块的元素,如<代码> BosixAyOnter元素> />代码或完全创建一个新的块。修改中的

< P>嵌套元素是一个强>已知的问题< /强>。有很多变通办法

可变方式 将块元素存储在变量中。 并在修改器内创建元素时使用插值

.block {
  $block: &;

  &__element {
    property: value;
  }

  &--modifier {
    property: value;
    #{$block}__element {
      property: value;
    }
  }
}
请参见下面的输出

功能方式 1.创建一个返回块元素的函数。 它将获取父选择器并剪切
--
之前的单词(即块)。看起来很粗糙,但这是最简单的方法

@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;
     }
   }
}
请参见下面的输出

这两种方式都将输出到:
您可以在修改器旁边添加
&
,以获得类似于Toni的解决方案

.block{
&__元素{
规则:价值;
}
&--修饰语和{
规则:价值;
&__元素{
规则:价值;
}
}

}
如果有人使用更少,这将帮助你

@块:。父;
@{block}{
背景:红色;
&--修饰语{
背景:蓝色;
}
&__孩子{
字体大小:20px;
@{block}--修饰符&{
字体大小:40px;
}
}
}

您的预期结果是什么?谢谢。我还发现了一个很好的方法。不幸的是,目前它不适用于libsass,但在3.3版本发布时可能会起作用。现在,要找到使用mixin.BTW创建元素和修饰符的解决方案,变量方式将不会输出
.block--modifier.block_u元素{property:value;}
它将输出:
.block--modifier.block--modifier\uuu元素{property:value;}
我现在就是这样做的。
.block {
  property: value;
}

.block--modifier {
  property: value;
}

.block--modifier .block__element {
  property: value;
}