BEM - 在哪里包含特定页面的修饰符?

BEM - Where to include modifiers for specific pages?

我正在尝试使用 BEM 命名约定,但在决定在何处包含特定页面的修饰符时遇到了一些困难。

例如,假设我有一个橙色按钮:

<button class="btn btn-orange">Button A</button>

我的项目有 3 个不同的页面:

 - pageA.html - pageA.scss
 - pageB.html - pageB.scss
 - pageC.html - pageC.scss

pageB.html 上,按钮应该有一个 margin-top:30px。修改器这样写对不对:

.btn {
  padding: 5px 20px;
  background: orange;
  margin: 0

  &--margin-top {
    margin-top: 30px;
  }
}

仅针对特定页面包含这样的修饰符的最佳方法是什么?在这种情况下,那将是 pageB.html。我应该在 pageB.scss.buttons.scss 中包含该修饰符吗?

我认为您在这里混淆了两个概念 - BEM,即 命名约定 与构建项目的问题。两者彼此无关,而且我认为 BEM 在构建 SASS 文件方面没有固执己见。

但是,您在这里问了几个问题:

  1. 这样写修饰符是否正确? - 如果你想坚持 BEM 约定,这是正确的,虽然我会说,你选择的名字 .btn--margin-top 从长远来看可能不是很幸运 - 想象一下,你会想要包含另一个 btn 修饰符 margin-top 属性 设置为,假设 40px。你会如何命名它?
  2. 仅针对特定页面包含此类修饰符的最佳方法是什么? - 这些 CSS class 您通常不会制作对于特定页面。 BEM 的全部意义在于使您能够编写更模块化的 CSS,考虑到这一点,您应该使用这些 CSS classes,通过将它们分别分配给您的 Blocks/Elements/Modifiers。这里的技巧是确定标记中的 block/element/modifier 是什么。您将通过此实现的是可重用的 CSS,因此您可以通过添加 BEM classes.
    快速应用相同的 css 考虑 组件 ,而不是页面。您只想在 pageB 上使用它 - 只需将 btn--margin-top class 添加到您的 pageB 标记中即可。
  3. 我应该在 pageB.scss 或 .buttons.scss 中包含该修饰符吗? - 这取决于您如何构建项目,我会说通常,按钮和其他 UI 元素在大多数情况下对整个 website/webapp 是通用的,因此无需将它们 "attached" 用于特定页面(我认为您需要删除哪个概念,如果你想充分利用 BEM)。另外,适合自己的才是对自己有好处的,除非你不是在开发团队中工作,否则就坚持自己的方法,这样你以后就知道去哪里找东西了。

在生产站点中,我通过使用一个故意更具体的页面文件来解决这个问题。

另一个回答者是正确的,BEM 没有解决这个问题,但解决方案在 css 架构中可用。

我倾向于按如下方式构建项目:

  • 模块
  • 页数

每个都变得更加具体。

一个部分可能有一些特定的呈现按钮的方式,在这种情况下 sass 会像这样:

.section {
  .button--primary {
    // styles 
  }
}

对于页面,相同,但具有页面特定键:

.page {
  .button--primary {
    // styles 
  }
}

你甚至可以这样做:

.page {
  .section {
    .button--primary {
      // styles 
    }
  }
}

关键是掌握 sass 文件结构的特殊性。您的按钮文件不会更改,您可以确定将其放在站点 HTML 的任何位置并使其正确呈现,并且作为一个模块,它应该只包含您希望在整个站点范围内应用的样式.例如:

.button--call-to-action {
  background-color: $brand-colours__call-to-action;
}

(连字符用于表示 call-to-actionbutton 的变体,下划线用于表示 call-to-action 是属于 brand-colours)

您的边距顶部将在您的 sass 的一部分中简单定义为 margin-top: 20px;,将其效果限制在网站的所需部分。

顺便说一句,通常会发现特定页面文件中的几乎所有内容都可以进一步重构为部分和模块的变体,这意味着它们通常最终都是空的。