【问题标题】:Are SMACSS, BEM and OOCSS not as portable?SMACSS、BEM 和 OOCSS 不便携吗?
【发布时间】:2015-08-10 12:17:12
【问题描述】:

所以我对 OOCSS 有疑问。它应该更便携,但与我通常做的事情相比,我发现它不那么便携了。

我的例子:

我有一个小部件推荐。在主要内容主体(具有白色背景)中,推荐使用黑色字体。但在页脚(蓝色背景)中,推荐信需要使用白色字体。

在 OOCSS 之前,我会做这样的事情:

#main-content .testominial {
  color: #000000;
}
#footer .testominial {
  color: #FFFFFF;
}

使用这种“旧”方法,我可以将我的小部件从内容区域拖到页脚,颜色就可以正常工作 - 我不需要更改小部件的 CSS 或 DOM 类。

使用新的 OOCSS/BEM,我不应该将 .testimonial 类耦合到 ID(或位置),而是应该像这样子类化它:

.testominial {
  color: #000000;
}
.testominial--footer {
  color: #FFFFFF;
}

这样做的问题是我不能再将我的推荐从内容区域拖到页脚而不进入 DOM 并更改推荐小部件上的类 - 它的可移植性较差,因为它需要开发人员手动干预;而在编辑器可以直接拖动它并且样式是自动的之前。

我错过了什么吗?似乎没有可靠的真实示例?

【问题讨论】:

  • 是的,这就是为什么我没有使用这些模式的原因,它们基本上违背了 CSS 选择器的设计原理。
  • imo,BEM/OOCSS 的目的是防止在一个“组件”中进行更改并在其他地方显示“中断”的“意外后果”。它通过类名“限制”CSS“级联”来做到这一点。这有助于重复使用的事实是一个好处。它当然有助于维护。这也让我们更容易理解 CSS 的作用和影响,因为我是程序员而不是设计师,也不是 CSS 专家。
  • @RyanVincent 重用不仅仅是一种奖励。这是 Nicole Sullivan 在Our best practices are killing us (OOCSS) 中的有力论据。而且,BEM 是一种“用于创建 Web 应用程序的技术”,BEM 有助于进行代码分解,即重用。
  • @Tarh,要点——我确实怀疑在我的评论中添加这样措辞的“重用”行是一个错误。我确实使用了“BEM”,它让使用 CSS 变得非常愉快。这当然是更可预测的。 :)
  • 回想起来,我应该更多地强调 OOCSS 而不是 BEM。我只是想弄清楚如何在没有 a) 用户添加任何类或代码的情况下重用一个小部件以使其看起来有所不同,并且 b) 使用 Nicole Sulivans 概念

标签: html css bem oocss smacss


【解决方案1】:

使用这种“旧”方法,我可以将我的小部件从内容区域拖到页脚,颜色就可以正常工作 - 我不需要更改小部件的 CSS 或 DOM 类。

如果你将元素.testominial从容器.main-content“拖”到容器.main-footer,那就是你改变了DOM。所以你也可以在 CSS 类中更新修饰符,没有额外的成本。

BEM 的目的是使 CSS 类可重用。以下修饰符可以在各种环境中重复使用。

CSS:

.testominial {
}
.testominial--darkFg {
    color: #000;
}
.testominial--lightFg {
    color: #FFF;
}

HTML:

<main class="main-content">
    <div class="testominial testominial--darkFg">...</div>
</main>
<footer class="main-footer">
    <div class="testominial testominial--lightFg">...</div>
</footer>

使用旧方法,每次在新容器中需要新块 .testominial 时,都必须更改 CSS 代码。 HTML 和 CSS 是强耦合的,有些 CSS 代码会重复。

使用 BEM 方法,每次设计人员添加块外观的新变体时,您都必须添加一些 CSS 代码。 HTML 和 CSS 耦合度更低,CSS 被更好地重用。

【讨论】:

  • 所以@Tarh,看着你的HTML sn-p,当你拖动小部件时,你必须手动将类“testominial--darkFg”或“testominial--lightFg”添加到小部件类列表中这页纸。我们的用户将无法做到这一点。我们需要它们能够在不编码的情况下进行拖放。
  • @gjok 也许 BEM 不适合您的用例?如果您的小部件需要根据容器功能调整其外观,那么您不能使用纯 BEM 方法。根据定义,在 BEM 中,块是上下文无关的。
  • 除了使用“旧方法”之外,我看不到任何解决方法。 OOCSS 告诉我们不要将我们的模块绑定到父位置,它还声称使我们的组件更可重用 - 但这里有一个重大冲突,因为位置通常定义外观,如我的示例所示。 OOCSS 如何解决这个问题?
  • 在你的类名中包含“dark”和“light”表明你的类名是伪装的内联样式以及因式布局。
  • @recursive 我明白了 - 显然我永远不会使用颜色名称,但它们始终是深色或浅色 - 这是要求。如果它永远一成不变,那么它不是问题。
【解决方案2】:

您需要考虑删除testimonial 命名以及footer

考虑这个例子:

.primary-box { }
.primary-box--reduced { }
.primary-box--standout { }

在示例中,类完全独立于它们的页面上下文。结果是这些类是完全可重用的。页面上的任何框都可以采用上述类并期望完全按照定义进行样式设置。

例如,您可以:

<header>
    <div class='primary-box primary-box--reduced'></div>
</header>
<div class='content-box'>
    <p class='primary-box primary-box--standout'></p>
</div>
<footer>
    <div class='primary-box primary-box--reduced'></div>
</footer>

现在,当设计师回来并调整突出框的填充时,您可以直接进入这些样式并调整它们,确信唯一会受到影响的区域将是 HTML 中具有这些类的区域。

此外,当您决定将 .primary-box--reduced&lt;header&gt; 移到其上方的菜单栏或页脚时,您可以确信样式会完全出现。

当您在某处需要另一个元素时,可能是primary-box--standout,或者只是标题中的默认primary-box,您只需创建它并添加类,它们的样式将完全遵循。

你也永远不会继承意想不到的风格。

这是一个非常真实的例子,我最近建立的一个网站几乎都是这样建立的,我说几乎都是因为我还在学习,但我可以保证我在快速上遇到的问题最少- 具有非常流畅的设计的移动项目是具有非特定上下文的项目。

重要的是缺乏上下文。在第一个示例中,.testimonial--footer 非常依赖于上下文,您确实只需要在页脚的推荐信中使用它。

就像魔法一样CSS Wizardry cover this exact topic

编辑:我添加了这个示例来帮助对我的答案发表评论。这不是 BEM 或 OOCSS,尽管它更接近于the SMACSS approach。这是我解决 css 问题的方法,是一种混合 BEM / SMACSS 方法:

按顺序加载:

  • 模块文件,如.primary-box
  • 页面部分文件,例如.header.call-to-action
  • 页面文件,如.about-us.contact

每个文件变得越来越具体,同时构建更复杂的模块。基于上面的示例并希望对 OP 有所帮助,您可以看到如下样式:

.header {
  .primary-box {
    color: #000;
  }
}

这将使用更具体的嵌套类表示法覆盖模块样式。请注意,我仍然会避免使用像 .header 这样的类名 - .banner-standout 会更好,因为它可以在任何地方重复使用而不会混淆

接下来,你甚至可以看到:

.about-us {
  .header {
    .primary-box {
      color: #f00;
    }
  }
}

我发现这在上下文的实际项目中非常有效,同时保留了 BEM 的上下文无关功能,尽管我也敦促尽可能将这条链向上推到模块中。如果我识别出新的通用页面部分或模块并适当地重新组织命名和文件,生活会更轻松。在一个代码经过仔细重构的项目中,页面文件中没有任何内容。

【讨论】:

  • 谢谢托尼,很高兴看到更多的例子,但尽管我试图让我的问题简洁,但我认为我的主要关注点仍然被忽略了。我的观点是我确实需要我的块依赖于上下文。你说无论我把html放在哪里,样式都会出现,但那是我不想要的。在页脚中,字体颜色需要为白色,但主体需要为黑色,以便有 上下文依赖。目前我们在屏幕上拖动小部件,并且在旧方法中(参见我的示例)我们不需要手动将类更改为小部件,因为父 ID 管理它。
  • 看看这篇文章中的答案:stackoverflow.com/questions/22566179/bem-block-naming-nesting 它展示了我面临的可饮用性问题的完美示例。如果要将 'nav' 从 'content' div 移动到 'sidebar' div,则需要手动将所有子元素的 'nav--content' 类替换为 'nav--sidebar'。 - 这就是我不便携的意思。谢谢 - 请帮忙。
  • @gjok - 请参阅编辑,我添加了一个我使用过的实际示例,可以在上下文很重要的情况下使用 BEM 的力量
  • 谢谢。所以这基本上编译成我在原始帖子中举例说明的格式,对吧?这意味着如果页脚上下文很重要,基本上可以使用页脚上下文 - 换句话说,BEM 不适用于此类问题?对吗?
  • 如果没有 .box--footer.box--header,BEM 并没有真正的解决方案,这并没有什么不同。
猜你喜欢
  • 2014-12-23
  • 2021-09-26
  • 2014-09-03
  • 2014-05-24
  • 1970-01-01
  • 2013-05-30
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多