20

我想在我的 Sass 库中实现类似于 BEM 模型的东西。但我正在努力寻找一种干净的方法来做到这一点。

例如,我想为一个通用元素声明一个“基本”样式,然后用有用的变体对其进行扩展:

.container {
  margin: 10%;
  background: #eee;

  &-featured {
    border: 2px solid #999;
  }

}

这里的问题是生成的.container-featured类只包含边框属性——Sass 不包括其“父”类的边距和背景。

因此,您最终不得不在标记中的类上加倍以获得所需的结果:

<div class="container container-featured">
  ...
</div>

是否有某种方法可以将父类中的属性拉到该修饰符类中,这样您只需在标记中引用修饰符类就可以获得相同的视觉结果?

<div class="container-featured">
  <!-- has margin, background, and border styles via just modifier class -->
</div>

我试过使用mixins来做到这一点,但事情很快就会变得冗长和重复:

@mixins container {
  margin: 10%;
  background: #eee;
}

.container {
  @include container;

  &-featured {
    @include container;
    border: 2px solid #999;
  }

}

是否有一种简单、干净的方法可以使用 Sass 实现这一目标?

4

2 回答 2

27

您正在寻找的是@extend指令。 @extend允许您将一组 CSS 属性从一个选择器共享到另一个选择器。这意味着您只需要使用container-featured该类。

例子

.container {
  margin: 10%;
  background: #eee;

  &-featured {
    @extend .container;
    border: 2px solid #999;
  }
}

编译为:

.container,
.container-featured {
    margin: 10%;
    background: #eee;
}

.container-featured {
    border: 2px solid #999;
}
于 2014-10-21T10:50:36.810 回答
1

你应该在 BEM 中使用 mixin 而不是在 Sass 中!

Mixin 就是这样——在同一个 DOM 节点上使用多个块和/或元素。

单个 DOM 节点可以表示:

  • 几个街区b-menu b-head-menu
  • 块和同一块的元素b-menu b-menu__layout
  • 一个块和另一个块的元素b-link b-menu__link
  • 不同块的元素b-menu__item b-head-menu__item
  • 一个带有修饰符的方块和另一个方块b-menu b-menu_layout_horiz b-head-menu
  • 几个带有修饰符的不同方块b-menu b-menu_layout_horiz b-head-toolbar b-head-toolbar_theme_black

阅读更多内容:http ://bem.github.io/bem-method/html/all.en.html,Mixin部分。

您也可以使用 i-blocks(抽象块),因此您的 .container 将是 .i-container,阅读更多:http ://bem.github.io/bem-method/html/all.en.html ,部分命名公约。

使用 Sass,您可以将 i-block 实现为

<div class="container-featured">
  ...
</div>

%i-container {
  // abstract block styles
  margin: 10%;
  background: #eee;
}

.container-featured {
  @extend %i-container;
  border: 2px solid #999;
}

在没有 Sass 的情况下,BEM 中的 mixin 如下所示:

<div class="i-container container-featured">
  ...
</div>

.i-container {
  // abstract block styles
  margin: 10%;
  background: #eee;
}

.container-featured {
  border: 2px solid #999;
}
于 2015-01-12T12:26:26.257 回答