Why Does Bem Often Use Two Underscores Instead of One for Modifiers

Why does BEM often use two underscores instead of one for modifiers?

Double Underscore is used to define sub element of a block.

i.e:

<nav class="main-nav">
<a class="main-nav__item" href="#">Text</a>
</nav>

Where main-nav is a block & main-nav__item is a sub element.

This is done because some people might name their block like this main_nav which will create confusion with single underscore like this : main_nav_item

Therefore double underscore will clarify stuff like this: main_nav__item.

Confusion with BEM modifiers

The answer depends on many things.

First, how much logic and appearance have "panel--with-chrome" and "panel--fullscreen" modifiers. And also on what kind this logic is.

If "panel--with-chrome" brings a lot of CSS properties and special JS functionality, I would toggle it in JavaScript when applying "panel--fullscreen".

It also depends on a JavaScript framework you use. In "i-bem.js" which we use at Yandex it's easy to react to appending a modifier:

  • A square changes size modifier when after a click
  • Reacting on applying a modifier

But if the framework you use doesn't allow to express such a reaction handy, this answer won't work that great for you.

In the other case, when "panel--with-chrome" has not very much properties and doesn't bring any JavaScript logic to a page, I would redefine those CSS properties in "panel--fullscreen" class.

To sum up, there is no universal solution and strict rules to follow. You should decide yourself what will be useful in your case. The decision should depend on many things:

  • if you expect your project to be maintained in the future, which solution will be easier to support?
  • capabilities of the JavaScript framework you use
  • performance stuff

    Not in this particular case, but sometimes we measure speed of rendering for variants we are choosing from.
  • opinion of the other guys, if you work in team
  • file structure of your project

    We, here at Yandex, store CSS and JavaScript for a block in the same block folder. So, it is not a problem to share logic between CSS and JavaScript since they all are in one place.

    But if you keep your JavaScript files separately, this can influence on how comfortable it is to support shared logic.

And so on...

The css BEM concept

First of all naming and structure is a personal thing. Although BEM concept is quite clear. It's a guideline, not a law.

Block:
How many blocks, element or modifiers you have depends on how much you like to reuse your own code. The number of blocks (repeating elements) can be as big or small as what you desire in your own project. My own guidelines are that I only use a block when I know the situation will be repeated.

CSS guidelines for blocks:

  1. Use class name selector only
  2. No tag name or ids No dependency on
  3. other blocks/elements on a page

Element:
The element part of BEM is the block it's "static" content. This can be non-repeated elements like single use heading styles, list styles, graphical elements etc. You never mix an other blocks elements inside it's own block.
Example:

GOOD:

<div class="logo">
<img src="/" class="logo__image">
</div>

BAD:

<div class="logo">
<img src="/" class="branding__logo">
</div>

CSS guidelines for elements

  1. Use class name selector only
  2. No tag name or ids
  3. No dependency on other blocks/elements on a page

Modifier:
Modifiers can be used on blocks and elements depending on how much you want to change the layout when an action happens. This can be highlighting something to completely change the designs look. Or just hide stuff.

CSS guidelines for modifiers

  1. To alter elements based on a block-level modifier
  2. To alter elements based on a element modifier

More about BEM can be found here: http://getbem.com/

Example of your code:

<!-- Begin block: topbar --><div class="topbar">  <div class="topbar__content">        <!-- Begin block: user -->    <div class="user">      <img class="user__image" src="image/1.jpg" alt="Sample Image">      <div class="user__meta">        <h3 class="user__username user__username--red"> Trump </h3>      </div>    </div>
<!-- Begin block: nav --> <ul class="nav"> <li class="nav__item nav__item--active"><a class="nav__link">One</a></li> <li class="nav__item"><a class="nav__link">Two</a></li> <li class="nav__item"><a class="nav__link">Three</a></li> </ul> </div></div>

CSS trends with naming class and id with dash underscore?

The double underscore follows the BEM methodology. It is basically a way of naming classes so that later it becomes easy for the user to understand.

The guiding principle behind BEM seems to be "when designing a page, think in terms of reusable widgets". Which is pretty much the standard way you should be writing your semantic HTML.

Learn more about BEM here: BEM methoodology

How to avoid redundant for something like BEM modifiers

This is a typical weakness of BEM. I have search for long, but do not seen any good solution for this so I make my own.

At first I would change the class name. Because UL element should be call 'product-desc-list'. The LI element 'product-desc', as this is in fact exactly a product description for a product.

The more important is the condition of the product. Therefore the selection of the element should be mentioned first. This allows several blocks to be used for one component.

The first is the component definition. The next define possible states like selected, in progress etc.

Here is an example for illustration

// your product in default definition. .product-desc {    &--link {    text-decoration: underline;  }}
// your product in mark state definition.mark { .product-description { &.--link{ font-weight: bold; } }}
<ul class="product-desc-list">  <li class="product-desc">    <a class="product-desc--link">Param1</a>  </li>  <li class="product-desc mark"> <!--add class .mark-->    <a class="product-desc--link">Param1</a>  </li></ul>

BEM - Where to include modifiers for specific pages?

I think you're confusing two concepts here - BEM, which is Naming Convention with the problem of structuring your projects. Both have nothing to do with each other, and I think BEM is not opinionated in terms of structuring your SASS files.

But, there's a couple of questions you ask here:

  1. Is it correct to write the modifier this way? - it is correct if you want to stick to BEM convention, although I would say, the name you picked .btn--margin-top might not be very fortunate in a long term - imagine, you'll want to include another btn modifier with margin-top property set to, let's say 40px. How will you name it?
  2. What is the best way to include a modifier like that only for a specific page? - These CSS classes you are usually not making for specific page. Whole point of BEM is to enable you, to write more modular CSS, and having this in mind you should use these CSS classes, by assigning them to your Blocks/Elements/Modifiers respectively. Trick here is to determine what is a block/element/modifier in your markup. What you'll achieve by this is reusable CSS, so you can quickly apply same css, by adding BEM classes.

    Think in terms of Blocks or Components, NOT pages. You want to use it only on pageB - just add btn--margin-top class to your pageB markup.
  3. Should I include that modifier inside the pageB.scss or .buttons.scss? - it depends on how you structure your project, and I would say that usually, buttons and other UI elements, are in most cases common to whole website/webapp, so there is no need of having them "attached" to specific page (which concept I think you need to drop, if you want to take full advantage of BEM). Besides, whatever suits you will be good for you, and unless you're not working within a team of developers, just stick to your own method, so you'll know in future where to look for things.

What is BEM methodology?

BEM is a naming methodology. It stands for Block Element Modifier and it's aim is to facilitate modularity and make styles and classes a lot easier to maintain.

It's not easy to explain it in a reply, but I can give you the basic idea.

So if you're thinking of a menu, then the whole element / component structure would be:

Block: menu
Element: item
Modifier(s): horizontal, vertical

And by following standard BEM conventions, you would write something like this in CSS:

html,body {  height: 100%;}
.menu { display: block;}
.menu__item { display: inline-block; line-height: 30px; width: 100px;}
.menu--horizontal { width: 100%; height: 30px;}
.menu--vertical { width: 100px; height: 100%;}
.menu--horizontal .menu__item { border-right: 1px solid #e5e5e5; text-align: center;}
.menu--vertical .menu__item { border-bottom: 1px solid #e5e5e5; text-align: left;}
<div class="menu menu--horizontal">  <div class="menu__item">Home</div>  <div class="menu__item">About</div>  <div class="menu__item">Contact</div></div>


Related Topics



Leave a reply



Submit