What is the BEM point that defines descendant class names in the presence of SCSS?

I am trying to pick up and understand the arguments regarding CSS naming conventions such as BEM or SUITCss. I find it difficult to understand the meaning of descendant class names in the presence of SCSS.

For instance:

<ul class="menu"> <li class="menu__item"></li> <li class="menu__item"></li> <li class="menu__item"> <a href="#" class="menu__item_link">link</a> </li> </ul> .menu { .menu__item { //styles .menu__item__link { //styles } } //or alternatively this syntax.. &__item { //styles } } 

With the ability to set rules in SCSS, I see no compelling reason to include ancestor class names in my code. Above, I have defined styles that should be used only for the โ€œelementโ€ that is inside the โ€œmenuโ€ using the names of the descendant classes. However, the nested structure already reports this! The rules for menu__item will only apply to the item under the menu, so why should I include this in the class name?

Why not:

 <ul class="menu"> <li class="item"></li> </ul> .menu { .item {//styles} } 

I understand that the descendant naming convention is more explicit and perhaps more future-friendly. I maintain, however, that it is only more explicit in html. If I wanted to consult how to build this menu module, I could just consult CSS and understand exactly how the menu contains elements nested inside.

I assume that one of the possible advantages is that I could write my css un-insested, for example:

 .menu { //styles } .menu__item { //styles } .menu__item__link { //styles } 

And then use "menu__item" anywhere, and in the class name it will still be obvious that it was the style of the item under the menu ... but then why define it as a descendant of the menu? (Another advantage, I suppose, is the short lines of the CSS identifier if things are not nested)

It seems to me that if the class name should be used as a descendant under another, then embedding in SCSS achieves this and clearly represents this logic. Why do we need BEM syntax?

I would like to hear someone explain the reasoning about this type of convention. I want to adhere to the so-called best practices, but it's hard for me to do it blindly without understanding the agreement.

+6
source share
2 answers

A few comments.

1 / First

 .menu { .menu__item { /* ... */ } //or alternatively this syntax.. &__item { /* ... */ } } 

The two SCSS syntaxes are not equivalent. The first uses a cascade (".menu.menu__item"), and not the second (".menu__item"). Only the second is BEM compatible.

2 / Why not a cascade:

 .menu { .item { /* styles */ } } 

BEM allows scalability. When we write CSS, we focus only on one small context: block. And each block can be reused repeatedly.

But cascades are not context-free. In your example, there is a "menu" block containing the "item" element. The context of the item item is the block menu. But the cascade breaks the separation of context for subunits. The syntax with the BEM prefix allows you to block nested blocks, the cascade does not. For instance:

 <ul class="menu"> <li class="menu__item"></li> <li class="menu__item"> <div class="other-block"> <span class="other-block__item"></span> </div> </li> </ul> 

Pay attention to the item item in the sub-block. With a cascade, instead of a prefix, it will be created using a rule that would be intended for the "item" elements of the parent block.

3 / This class name does not match BEM:

 .menu__item__link { /* styles */ } 

Elements do not provide any context. Only blocks provide contexts. The context of a is the context of its block. Thus, the โ€œlinkโ€ is not a descendant of the โ€œelementโ€ in the BEM tree. These two are brothers, regardless of their situations in the DOM tree. You should use:

 .menu { /* styles */ } .menu__item { /* styles */ } .menu__link { /* styles */ } 
+7
source

Let's start with the idea of โ€‹โ€‹BEM or SMACSS.

The main task that any methodology solves is the structuring and modulation of your code.

For example, BEM uses the following abstractions:

A block is an independent part of the user interface (for example, a feedback form),

An element - part of a block can not exist without a block (for example, a feedback form button)

Modifier - an assistant that allows you to change a block or element (for example, make a button larger or smaller).

SMACSS uses different abstractions: module, layout, base, state, theme. To clearly understand this idea, imagine that your html page contains logical layers,

1) BASE - you add css dumps, determine the font sizes H1, H2 ..., determine the colors. Thus, in the database you put things, and should not change.

2) LAYOUT - adds a grid or a separate page in the regions. 3) Module - an independent content item

3) STATUS - very close to the BEM modifier, but is associated with some action with the module, for example, is_hided, is_collapsed

4) Theme - can be used to override BASE.

So, to separate these abstractions, you have to follow a specific naming convention so that you can first take a look at what this class does. If you adhere to the naming convention, it is also much easier to support you in the project6 so that he easily explains to the members of the new team how the code is organized and how to write new code that looks like one person wrote it.

Its extremely important in large-scale projects with large teams.

In addition, naming conventions help reduce the number of descendant selectors that improve performance.

+3
source

Source: https://habr.com/ru/post/972099/


All Articles