【问题标题】:Sass BEM: avoid modifier duplication when element is inside a modifierSass BEM:当元素在修饰符内时避免修饰符重复
【发布时间】:2015-11-10 05:37:51
【问题描述】:

我能否以某种方式重构以下代码 sn-p 以摆脱 双修饰符声明

.block {
  &__element {
    rule: value;
  }
  &--modifier {
    rule: value;
  }
  &--modifier & {
    &__element {
      rule: value;
    }
  }
}

想要的输出:

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

【问题讨论】:

  • 您的预期结果是什么?

标签: sass bem


【解决方案1】:

您可以像这样将块放置在&--modifier 选择器中,使用块的类名而不是& 来定位它。

.block {
  &__element {
    rule: value;
  }
  &--modifier {
    rule: value;

    .block {
      &__element {
        rule: value;
      }
    }
  }
}

但是,这可能不是最好的 BEM 解决方案,您应该考虑将嵌套块重命名为包含块的元素,例如 .block__another-element 或完全创建一个新块。

【讨论】:

    【解决方案2】:

    在修饰符内嵌套元素是一个已知问题。有很多解决方法。

    可变方式

    将块元素存储在变量中。

    在修饰符内创建元素时使用它进行插值。

    .block {
      $block: &;
    
      &__element {
        property: value;
      }
    
      &--modifier {
        property: value;
        #{$block}__element {
          property: value;
        }
      }
    }
    

    请参阅下面的输出。

    作用方式

    1。创建一个返回块元素的函数。

    它将获取父选择器并剪切--(即块)之前的单词。看起来很hacky,但这是最简单的方法。

    @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;
    }
    

    【讨论】:

    • 谢谢。我还发现了一个很棒的BEM-constructor。不幸的是,目前它不适用于 libsass,但可能会在 3.3 版本发布时使用。
    • 现在为使用 mixin 创建元素和修饰符找到解决方案。
    • BTW,变量方式不会输出.block--modifier .block__element {property: value;}会输出:.block--modifier .block--modifier__element {property: value;}
    【解决方案3】:

    您可以在修饰符旁边添加&,以获得类似于 Toni 的解决方案。

    .block {
    
      &__element {
        rule: value;
      }
    
      &--modifier & {
        rule: value;
        
        &__element {
          rule: value;
        }
      }
    }

    然而,这需要.block 是一个根选择器,而不是嵌套在任何其他选择器中。

    只是另一种可能的解决方案。不过,在大多数情况下,我仍然更喜欢 Toni 的解决方案。

    【讨论】:

    • 这就是我目前的做法。
    【解决方案4】:

    如果有人少用,这会对你有所帮助!

    @block:.parent;
    @{block}{
        backgroung:red;
        &--modifier{
            backgroung:blue;
        }
        &__child{
            font-size:20px;
            @{block}--modifier & {
               font-size:40px;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 2012-12-14
      • 1970-01-01
      • 2019-11-03
      • 2017-03-07
      • 1970-01-01
      相关资源
      最近更新 更多