【问题标题】:SASS BEM WildcardsSASS BEM 通配符
【发布时间】:2021-02-22 00:57:10
【问题描述】:

我使用 BEM(至少是它的修改版)已经有一段时间了;并且最近从编写 CSS 转向 Sass,它似乎非常适合 BEM,但我不知道如何轻松实现通配符特异性。

例如;假设我有几个按钮:

<button
  class="BLOCK__ELEMENT BLOCK__ELEMENT--MODIFIER1"
>
  Click Me 1
</button>

<button
  class="BLOCK__ELEMENT BLOCK__ELEMENT--MODIFIER2"
>
  Click Me 2
</button>

<button
  class="BLOCK__ELEMENT BLOCK__ELEMENT--MODIFIER3"
>
  Click Me 3
</button>

在 CSS 文件中,我可以编写以下内容:

.BLOCK__ELEMENT {
  border-radius: 2rem
}

.BLOCK_ELEMENT--MODIFIER1 {
  background-color: red
}

.BLOCK_ELEMENT--MODIFIER2 {
  background-color: white
}

.BLOCK_ELEMENT--MODIFIER3 {
  background-color: blue
}

世界上一切都会好的

在 Sass 中,我可以将其简化如下:

.BLOCK__ELEMENT {
  border-radius: 2rem

  &--MODIFIER1 {
    background-color: red
  }

  &--MODIFIER2 {
    background-color: white
  }

  &--MODIFIER3 {
    background-color: blue
  }
}

这是一个很好的改进


但我真正想做的是将我的标记简化如下

<button
  class="BLOCK__ELEMENT--MODIFIER1"
>
  Click Me 1
</button>

<button
  class="BLOCK__ELEMENT--MODIFIER2"
>
  Click Me 2
</button>

<button
  class="BLOCK__ELEMENT--MODIFIER3"
>
  Click Me 3
</button>

并拥有看起来像这样的 Sass:

.BLOCK__ELEMENT {

  &* {
    border-radius: 2rem
  }

  &--MODIFIER1 {
    background-color: red
  }

  &--MODIFIER2 {
    background-color: white
  }

  &--MODIFIER3 {
    background-color: blue
  }
}

sass中有这样的通配符实现吗?

【问题讨论】:

    标签: html sass wildcard bem


    【解决方案1】:

    我有另一个可能的解决方案

    @use "sass:string"
    
    @mixin self() {
      $self: string.slice(#{&}, 2);
      
      @at-root &, [class*="#{$self}"] {
        @content
      }
    }
    
    .Block {
      @include self() {
        border-radius: 2rem;
      }
    
      &--modifier1 {
        background-color: red;
      }
      &--modifier2 {
        background-color: blue;
      }
      &--modifier1 {
        background-color: salmon;
      }
    
      &__element {
        @include self() {
          width: 50px;
        }
    
        &--modifier {
          background-color: skyblue;
        }
    
      }
    }
    

    这是这样编译的

    .Block, [class*=Block] {
      border-radius: 2rem;
    }
    
    .Block--modifier1 {
      background-color: red;
    }
    .Block--modifier2 {
      background-color: blue;
    }
    .Block--modifier1 {
      background-color: salmon;
    }
    
    .Block__element, [class*=Block__element] {
      width: 50px;
    }
    
    .Block__element--modifier {
      background-color: skyblue;
    }
    

    【讨论】:

    • 这太棒了;谢谢!这将极大地清理我的 HTML!我对我的课程有点强迫症,经常添加一个看起来像这样的课程:BLOCK BLOCK__ELEMENT BLOCK__ELEMENT--MODIFIER,这样我就可以一致地设置样式——但我讨厌标记中的开销。
    【解决方案2】:

    好的旧css怎么样? :)

    [class*="BLOCK__ELEMENT-"]
    

    【讨论】:

    • 我玩过那个;它可以工作——我希望有一个嵌套的通配符实现我可以在 scss 中实现——出于组织目的,我必须检查[class*=&amp;] 是否可以工作——它并不漂亮,但那会做这个把戏
    【解决方案3】:

    就像说 Sueno,您可以使用 [class*="BLOCK__ELEMENT--"] 并执行以下操作:

    .BLOCK_ELEMENT {
    
      @at-root &, [class*="BLOCK_ELEMENT"] { // or just @at-root [class*="BLOCK_ELEMENT"]
        border-radius: 2rem;
      }
    
      &--MODIFIER1 {
        background-color: red
      }
    
      &--MODIFIER2 {
        background-color: white
      }
    
      &--MODIFIER3 {
        background-color: blue
      }  
    }
    

    【讨论】:

    • 这行得通,所以谢谢你,但我真的希望有一些东西使用像[class*=&amp;]这样的引用如果你嵌套更深,使用``` .Block { &_ELEMENT {border-半径:2rem; &--MODIFIER1 { 背景颜色:红色; } } } ``` 最好在块中使用[class*=&amp;] 之类的东西来表示块,然后在元素中再次表示元素我正在寻找的东西可能是不可能的(语法明智),但是您的回复确实提供了一个可行的解决方案(我只是不想冗余地编写块或块元素)
    • 我将把它打开一段时间,看看你或其他人是否有减少重复的方法,但如果没有,我会接受并关闭它——感谢您抽出宝贵的时间;干杯
    猜你喜欢
    • 2018-08-28
    • 1970-01-01
    • 2020-08-07
    • 2018-05-19
    • 2015-11-09
    • 2016-12-10
    • 2016-03-05
    • 2014-02-24
    • 1970-01-01
    相关资源
    最近更新 更多