首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SMACSS和BEM:如何在模块中定位模块?

SMACSS和BEM:如何在模块中定位模块?
EN

Stack Overflow用户
提问于 2014-07-13 16:39:45
回答 4查看 2.7K关注 0票数 15

注意:我使用单词Module,它在边界元中称为。另外,使用修改后的边界元命名约定BLOCK__ELEMENT--MODIFIER,请在您的答案中使用。

假设我有一个类似于以下内容的.btn模块:

代码语言:javascript
复制
.btn {
  background: red;
  text-align: center;
  font-family: Arial;

  i {
    width:15px;
    height:15px;
  }
}

我需要创建一个.popup-dialog模块,其中包含一个.btn

代码语言:javascript
复制
.popup-dialog {
  ...
  .btn {
    position: absolute;
    top: 10px;
    right: 10px;
  }
}

在SMACSS和BEM中,您应该如何处理模块内部的定位?

在您的回答中,请确定正确的解决方案,并分析以下方法:(注意,下面的所有示例都是在上述CSS的基础上构建或修改的)

方法1

重写.popup-dialog中的原始.popup-dialog

CSS

代码语言:javascript
复制
.popup-dialog {
  ...
  .btn {  // override the original .btn class
    position: absolute;
    top: 10px;
    right: 10px;
  }
}

标记

代码语言:javascript
复制
<div class="popup-dialog">
  ...
  <button class="btn"><i class="close-ico"></i> close</btn>
</div>

方法2

.popup-dialog中添加一个子类

CSS

代码语言:javascript
复制
.popup-dialog {
  ...
  .popup-dialog__btn {
    position: absolute;
    top: 10px;
    right: 10px;
  }
}

标记

代码语言:javascript
复制
<div class="popup-dialog">
  ...
  <button class="btn popup-dialog__btn"><i class="close-ico"></i> close</btn>
</div>

方法3

带有修饰符的子类.btn

CSS

代码语言:javascript
复制
.btn--dialog-close {
  position: absolute;
  top: 10px;
  right: 10px;
}

标记

代码语言:javascript
复制
<div class="popup-dialog">
  ...
  <button class="btn btn--dialog-close"><i class="close-ico"></i> close</btn>
</div>

方法4

带有布局类的子类.btn

CSS

代码语言:javascript
复制
.l-dialog-btn {       // layout
  position: absolute;
  top: 10px;
  right: 10px;
}

标记

代码语言:javascript
复制
<div class="popup-dialog">
  ...
  <button class="btn l-dialog-btn"><i class="close-ico"></i> close</btn>
</div>
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-07-19 13:01:07

在最近的一个大型项目中,我一直在努力解决这个问题,我为你把这个问题引起人们的关注而鼓掌。

我担心这个问题没有一个“正确”的解决方案,而且它会有一些基于意见的解决方案。然而,我将尽量客观地看待你的四种方法,包括哪些对我的团队有效,哪些对我的团队无效。

另外,我将假设如下:

  • 您熟悉SMACCS方法(您阅读了这本书并在至少一个项目中实现了它)。
  • 您只对CSS类名使用(修改后的) BEM命名约定,而不使用BEM方法开发堆栈的其余部分。

方法1

这显然是最糟糕的做法,有几个缺点:

  • 它通过使用基于上下文的选择器在.popup-dialog.btn之间创建了一个紧密的耦合。
  • 将来您可能会遇到专用性问题,假设将来会在.popup-dialog中添加额外的.popup-dialog元素。

如果您需要使用未更改的类名,我建议至少通过使用直接子选择器来降低适用性的深度。

CSS:

代码语言:javascript
复制
.popup-dialog {...}

.popup-dialog > .btn {
  position: absolute;
  top: 10px;
  right: 10px;
}

方法2

这实际上非常接近我们的解决方案。我们在我们的项目中设置了以下规则,并且它被证明是健壮的:“模块不能有外部布局,但可以布局其子模块”。这在很大程度上是受SUITCSS框架的@necolas惯例的启发。注意:我们使用的是概念,而不是语法。

https://github.com/suitcss/suit/blob/master/doc/components.md#styling-dependencies

我们在这里选择了第二个选项,并将子模块封装在其他容器元素中。是的,它创造了更多的标记,但它的好处是,我们仍然可以应用布局时,使用第三方的内容,我们不能控制HTML (嵌入从其他网站,等等)。

CSS:

代码语言:javascript
复制
.popup-dialog {...}

.popup-dialog__wrap-btn {
  position: absolute;
  top: 10px;
  right: 10px;
}

HTML:

代码语言:javascript
复制
<div class="popup-dialog">
  ...
  <div class="popup-dialog__wrap-btn">
    <button class="btn"><i class="close-ico"></i> close</button>
  </div>
</div>

方法3

这可能看起来很干净(扩展而不是覆盖),但事实并非如此。它将布局与模块样式混合在一起。如果您有另一个模块需要为“关闭”按钮设置不同的布局,那么在.btn--dialog-close上设置布局样式将不会有什么用处。

方法4

这与方法3基本相同,但语法不同。布局类必须不知道其布局的内容。另外,我不太喜欢这本书中所建议的l-prefix语法。根据我的经验,这会造成更多的混乱,而不是帮助。我们的团队完全放弃了它,我们只是把一切都当作模块来处理。但是,如果我需要继续使用它,我会尝试将布局从模块中完全抽象出来,这样您就有了一些有用的、可重用的布局。

CSS:

代码语言:javascript
复制
.l-pane {
  position: relative;
  ...
}

.l-pane__item {
  position: absolute;
}

.l-pane__item--top-right {
  top: 10px;
  right: 10px;
}

.popup-dialog { // dialog skin
  ...
}

.btn { // button skin
  ...
}

HTML:

代码语言:javascript
复制
<div class="popup-dialog l-pane">
  <div class="l-pane__item l-pane__item--top-right">
    <button class="btn"><i class="close-ico"></i> close</button>
  </div>
</div>

我不会因为这种方法而责怪任何人,但根据我的经验,并不是所有的布局都可以以合理的方式抽象出来,并且必须单独设置。这也使其他开发人员更难理解。我把网格布局排除在这个假设之外,它们很容易掌握,而且非常有用。

给你拿着。基于上述原因,我建议尝试修改后的方法2。

希望能帮忙。

票数 18
EN

Stack Overflow用户

发布于 2014-07-15 12:39:26

边界元

如果您不修改.btn内部的.popup-dialog,第一个方法是最好的。

如果您需要修改.btn,根据边界元方法,您必须使用修饰符类,如.btn_size_s

如果您的修改不是直接与.btn连接,并且怀疑将来是否可以重用,例如您必须在弹出窗口中将.btn浮动到右,则可以像使用.popup-dialog__btn一样使用混音。

SMACSS

同样,如果您需要将一个块放置在其他-follow的第一个方法中。

如果您需要任何修改,有两种方法:子类和后代选择器。

如果您的修改可以在将来重用--使用子类,比如.btn-size-s。如果修改与某些特定模块紧密相连--更好地使用后代选择器。

更新:

补充几点来澄清我的答案:

首先,方法4是不可接受的--您将模块和布局混合在一起是不好的做法,因为布局类负责网格和页面段几何,模块独立于布局之外,不应该知道它放置的部分。

现在让我评论一下其他方法,以及它的最佳用法是什么:

方法1 -考虑以下情况:您有Popup模块和“关闭”Button模块。PopupButton不做任何事情,没有任何修改,没有浮标或margings,它只是它的孩子。这种情况下,这种方法是最好的。

Approach 2 --另一种情况是:Popup有子Button,但是我们必须在右边添加额外的上限和浮动Button。正如您所看到的,这种修改与Popup紧密耦合在一起,不能用于其他模块。这种“本地”修改是这种方法的最佳使用。在边界元中,这种方法也称为mix

Approach 3 --最后一种情况:带有子按钮的Popup,但是我们需要更大的Button,这样的修改按钮可以重用,并且可以用于其他模块和页面。在边界元中,its称为修饰符

为了标记A2和A3之间的主要区别,让我们从Popup中删除Button并将其放置在其他地方。A3仍然会影响ButtonA2而不是

因此,要使用作为的模块,您可以使用A1或A2,在模块修改时应该使用A3,而不依赖于上下文。

票数 2
EN

Stack Overflow用户

发布于 2014-07-23 09:11:41

还有另一种可能适合您需要的约定:https://ncss.io

目标:

CSS的可预测语法,它提供有关HTML模板的语义信息。

  • 哪些标签、组件和区段受到影响?
  • 一个类与另一个类的关系是什么?

示例:

代码语言:javascript
复制
<div class="modal-dialog">
  ...
  <div class="wrapper-button-dialog">
    <button class="button-dialog">close</button>
  </div>
</div>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24724929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档