我可以以某种方式重构以下代码片段以摆脱双修饰符声明吗?
.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
}
&--modifier & {
&__element {
rule: value;
}
}
}
想要输出:
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
答案 0 :(得分:13)
将元素嵌套在修饰符中是已知问题。有很多解决方法。
在修饰符中创建元素时使用插值。
.block {
$block: &;
&__element {
property: value;
}
&--modifier {
property: value;
#{$block}__element {
property: value;
}
}
}
见下面的输出。
它将获得父选择器并在--
之前剪切单词(这是块)。看起来很讨厌,但这是最简单的方法。
@function block() {
$selector: str-slice(inspect(&), 2, -2);
$index: str-index($selector, '--') - 1;
@return str-slice($selector, 0, $index);
}
这将返回块的名称,因此您不必重复它。
.block {
property: value;
&--modifier {
property: value;
#{block()}__element {
property: value;
}
}
}
见下面的输出。
.block {
property: value;
}
.block--modifier {
property: value;
}
.block--modifier .block__element {
property: value;
}
答案 1 :(得分:1)
您可以使用块的类名而不是&--modifier
将块放在&
选择器中,而不是.block {
&__element {
rule: value;
}
&--modifier {
rule: value;
.block {
&__element {
rule: value;
}
}
}
}
。
.block__another-element
但是,这可能不是最好的BEM解决方案,您应该考虑将嵌套块重命名为包含块的元素,例如{{1}}或完全创建新块。
答案 2 :(得分:1)
您可以在修改器旁添加&
以获得类似于Toni的解决方案。
.block {
&__element {
rule: value;
}
&--modifier & {
rule: value;
&__element {
rule: value;
}
}
}
但是,这需要.block
成为根选择器,而不是嵌套在任何其他选择器中。
另一种可能的解决方案。但对于大多数情况,我仍然更喜欢Toni的解决方案。
答案 3 :(得分:1)
如果某人减少使用,这将对您有帮助!
@block:.parent;
@{block}{
backgroung:red;
&--modifier{
backgroung:blue;
}
&__child{
font-size:20px;
@{block}--modifier & {
font-size:40px;
}
}
}