
问候。 在本文中,我将告诉您如何更改BEM,保留其最佳功能并摆脱最差的功能。
那么首先,让我们谈谈BEM有什么问题吗? 也许什么都不需要改变,一切都很好?
BEM是一种允许您多次使用CSS / HTML / JS的方法。 她介绍了块,元素,修饰符和混合的概念。 开始使用它后,您了解到这正是您多年来一直在等待的东西,它是如此的方便,清晰和美观! 但是过了一段时间,这种发展的时刻开始出现,可以借助BEM加以解决,但这并没有带来愉悦感,最重要的是没有带来收益。 我在说什么 让我们看一下这些要点:
1.一次性块和物品
这个问题使我非常困扰,以至于我被迫写这篇文章。
块的概念意味着可以并且应该重用的实体,但是,在实践中,会创建大量的块,这些块只能应用一次。
例如,我们需要执行以下操作:在页面上放置标题,然后是文本字段和发送按钮,如图所示:

根据BEM,我们将做什么? 有几种选择:
- 创建一个表单块及其元素:标题,按钮,文本字段
- 为每个组件(按钮,文本框,标题)以及表单创建单独的块
- ...
无论我们选择什么,都会遇到一个问题:如何在所有这些块之间设置缩进?
如果选择第一个选项,则可以决定缩进表单的元素,因为这与方法并不矛盾。 但是,在这种情况下,我们破坏了该块的本质:它无法重用,因为它的内部标记仅适合当前情况。
如果我们选择第二个选项,则可以将某些块混合到窗体中,并且可以将该块的元素混合到窗体的组件中。 并且,因此,对于刚创建的块的元素,设置缩进。 这里出现了一次性块的问题:它们只能在一个地方使用! 由于组件在其他页面上的位置不同,因此无法再使用它们。
这个问题会生成一次性的块/元素,以及类型为
___size_
或
___place_----
___size_
___place_----
___size_
修饰符(用于缩进),
___size_
,这些修饰符只使用一次,会使标记文件和具有各自目录的项目变得混乱和文件。
这不仅适用于缩进,而且适用于块大小(例如,对于按钮,这通常会导致
line-height
),字体大小,缩进等变化。
2.长类名
甚至没有什么可谈的。 我认为没有人喜欢这样的标记:
<header class="section-header section-header_margin_select-sector"> <h2 class="section-header__title font font_face_calibri-bold section-header__title_size_select-sectors"> Select a sector, please: </h2> </header>
3.默认值或块主题
假设我们有一个按钮块。 您需要根据设计要求对其进行样式化。 但是在另一个项目中,还将有一个按钮类。 外观会有所不同,但某些样式将相同。 BEM建议做什么? 他说要创建一个主题修改器并将其设置为所有必需的元素。
但是,使用这种方法,将得到以下结果:
<input type="text" class="textbox textbox_theme_P2"> <button class="button button_theme_P2">Reset</button> <button class="button button_theme_P2">Submit</button> <button class="button button_theme_P2">Save as draft</button>
这是一堆混乱的代码,这很糟糕。
您批评-提供
我建议如何纠正这种耻辱? 我提出以下清单,该清单本质上是标准BEM的附加组件。
宣言-改进的BEM
A.1模块层和页面层
我建议将样式分为两部分:
第一部分是组件层。 这部分是根据所有(几乎*)BEM规则编写的。 它为可重复使用的块或组件(例如,按钮,文本字段,标题等)设置样式。
另一部分是页面层。 需要设置特定页面的块和元素的样式。 因此,这些块/元素将被使用一次(无论如何在一页上)。 BEM规则不适用于此处。 看起来像这样:
档案:
index.css
.___send-button { margin-bottom: 2px; font-size: 13px; } .___message-textarea { width: 240px; height: 300px; font-size: 14px; }
页面布局文件的名称是可选的。 最主要的是,它与页面的本质相匹配。 所有样式均以“ ___”开头,以免与标准BEM实体类混淆。 此外,类也不与BEM实体相关联-它们的名称仅反映应将其应用于什么。 还值得注意的是,页面布局的所有样式都位于一个文件中,因为它们与一页有关。
这种分离使我们能够解决第一个问题,而不会影响BEM的主要目标-创建样式/标记,以便可以重复使用它们。 这些样式将仅应用于一页,并且绝不会干扰组件布局中的组件样式。 因此,我们摆脱了一次性类,同时保持了重用块的能力并且不会违反范围。
在目录级别分隔组件和页面布局也很有意义。
*除清单的以下各段取消的规则外。A.2长类名
(实验性的,因此是可选项目*)
建议用以下内容替换部分标准命名系统:
对于块:
class=""
(不变)
对于带有修饰符的块:
class=" _"
(通过组合的选择器访问
.._
)
对于元素:
class="__"
(不变)
对于带有修饰符的元素:
class="__ _"
(通过
.__._
访问)
此项允许您获得有关修饰符的简短代码。 显然,元素不能做到相同。
重要的是,具有样式的文件应没有为仅由修饰符组成的选择器定义规则:
._active { background-color: #abcdef; }
*修饰符的类似命名可能会导致块/元素与其他块/元素混合的问题,但前提是两个实体可以具有相同的修饰符。 也就是说,通过为一个实体设置修饰符,我们为与该节点混合的每个人都设置了修饰符。A.3默认值和主题
这里的一切都很简单。 建议选择一个默认主题,但要为其指定样式,而不是在块文件中的块类中,而是在应该放置在主题文件中的块类中为其指定样式。 例如:
文件
button/button.css
.button { cursor: pointer; display: inline-block; }
文件
button/_theme/button_theme_P2.css
.button_theme_P2, .button { border-radius: 3px; border: 1px solid #f00; }
或按照第2款
.button._theme_P2, .button { border-radius: 3px; border: 1px solid #f00; }
因此,该主题成为标准主题,但是您可以根据需要直接使用它。

总结
此声明旨在解决根据BEM进行布局时出现的一些问题。 它的主要组成部分是对组件布局和页面布局的细分。 尽管宣言看上去颇具革命性,不合常规且大胆,但它解决了上述问题。 要全部使用,部分使用还是完全不使用-您可以自行决定。
PS:如果您现在正在愤怒地滚动整个页面以放置减号,请不要忘记写评论,否则您的减号将不会带来任何好处(
以及清单 )。