Login with github

Sometimes people write "BEM", sometimes "BEM 101". It's obvious what "BEM" comes from. But what is the source of "101" in the name..? I am so curious :)

Hi there,

I have a navigation list, each items will need unique styling such as an icon/image applied to it. I've seen this handled a couple of different ways so I thought I'd put it to the forum and gets peoples thoughts on it. The standard mark-up would be something like this:

<nav class="site-nav">
    <ul class="site-nav__list">
        <li class="site-nav__item"><a href="#" class="site-nav__link">Schools</a></li>
        <li class="site-nav__item"><a href="#" class="site-nav__link">Users</a></li>
    </ul>
</nav>

Originally I thought I'd use a modifier and add classes like site-nav__item--users for example. But quite a few sites I've looked at use an element instead, so site-nav__users. So in full...

<nav class="site-nav">
    <ul class="site-nav__list">
        <li class="site-nav__item site-nav__schools"><a href="#" class="site-nav__link">Schools</a></li>
        <li class="site-nav__item site-nav__users"><a href="#" class="site-nav__link">Users</a></li>
    </ul>
</nav>

What's the thinking behind this and is there a right/wrong answer? Thanks in advance!

Hi everybody,

Briefly about the main events in the BEM world over the last 4 months with the beginning of the year.

Libraries news

  • RC of the next major release of bem-core — 4.0.0-rc.1. The main changes concerned the improvement of i-bem.js. If you are ready — you can check this release on your projects. The stable version will be released soon. Don't forget to tell us about all the detected bugs.
  • major version of bem-components 3.0.0 that works with bem-core 3.0.1. Despite the fact that the release is major, update should be painless.
  • bem-history 3.2.0. The main change is a support for bem-core 3.x in bower.json. And, of course, a few bug fixes included.
  • renamed the organization bem-incubtaror in bem-contrib. New name much better reflects the organization's mission. If you use (or develop) any packages, you should update the paths to the repository (some time github supports redirects automatically). You can use the user manual.

Technology news

  • released two major and dozens of minor releases bem-xjst. The latest version is 6.5.1 Key changes:
    • BEMTREE
    • implemented support for ES6 arrow functions
    • made optional content escaping
    • supported JS-binding for elements
    • made mode to render the HTML without the /:
      instead of
    • removed some deprecated methods and functions.

Read more about all the changes in the release notes, which are written in detail to each release: https://github.com/bem/bem-xjst/releases.

Tools

Released ENB 1.3

Worked on the plugins for the ENB:

Site news

  • recently, we have partially updated our website bem.info — it became more modern, fast and beautiful
  • rolled out the Ukrainian version https://uk.bem.info, the translations into other languages will appear soon.

Events (only in Russian)

  • tadatuta@ held a webinar on three-tier architecture services on bem-xjst
  • Did two reports on Yandex.Subbotnik (frontend conference): https://events.yandex.ru/events/yasubbotnik/27-feb-2016/
  • Held another hackathon at the BEM, advanced modular Assembly and came up with a way to make friends BEMHTML-templates with React.

Interesting on the forum (in Russian)

Thank's and stay BEM'ed!

A week ago I took part in the hackathon in Yandex. It was a small and local(for Yandex) one, only for yandexoids and friends. It was a very technical hackathon about tools for developers like loaders, builders, template engines. So developers were doing something for themselves.

So how did I get there if I'm not a yandexoid - my college Anton invited me because we were doing stuff related to Yandex on my current job. It's an interesting project - I'll say a few words about it later - but I couldn't find time for it because of other duties. So this hackathon became a great opportunity to find time and complete the project.

A few words about our project. BEMXJST is a declarative template engine, very flexible and powerful. So you can describe some structures using logic and domain-specific functions. Also, there is another engine BEMHTML that takes BEMXJST-templates and BEMJSON(simply a subset of JSON) and after some magic we get HTML. So on my current job we have a library of UI components that uses BEMXJST and BEMHTML. We also have a library based on React renderer. The libraries have to be equal in functionality and appearance - so there has to be no difference for users. The main idea is somehow to tell React-lib to use BEMXJST-templates in its render function. This will give us the ability to develop markup in one place and not to copy-paste it. It's possible to implement another engine that works like BEMHTML but outputs data structures fittable for creating virtual-DOM. That's how the React render function works - it doesn't produce a real DOM but a structure that describes DOM so it can compare it with the real one and then decide is it required to update the real DOM. That's why we called our engine VIDOM.

Before the hackathon, we checked the idea and created some POC and I can say that it was almost ready and almost all the tests were green. But the code base was awful and there were bugs and we didn't check all the edge cases. So the goal for the hackathon was to complete the project and make it possible to merge into upstream.

I love hackathons because of their magic. Just imagine the Saturday morning, you want to relax and your body is tired and then you came to the place with a lot of people who are also tired but they want to work and they have the ideas and passion for doing it and it's really the thing that motivates me. So I was full of energy for the whole weekend. Also, it's a great pleasure to hang out and just work together, it's great fun definitely.

This particular hackathon was great for me because it was about tools and I'm interested in it. I like that there were no prizes or ratings or stuff like that. I believe that money or other prizes break the idea because what really matters is the pleasure of doing some stuff with friends and what you get at the end. And this is the real prize. I also felt the engineering culture that exists in Yandex and it's great.

Finally, we've done our tasks and created a pull request into the main project.

More details in russian here.

Source

Hi all! Is there any guide or examples to write plain js for blocks?

Thanks!

Hello!

I've been using the BEM approach for front-end web development a couple of years now (and it's just great!) but only yesterday I started to try out the BEMHTML template language. So far I like it a lot!

There's a couple of things though that I can't yet wrap my head around and can't find anything about in the docs either. So I hope to have some more luck here and hopefully also help others that might be facing the same problems.

Basically I would like to know how to be able to add custom CSS for a webpage that isn't directly block related. For example declarations for webfonts, normalize/reset css code, etc. I would still like to be able to use Stylus as preprocessor and have bem-tools generate and minify this CSS together with my blocks' CSS.

The same question goes for JS. What is the correct way to add JS libraries and custom JS code, preferably maintaining the possibility to have this combined/concatenated with the block level JS?

Thanks! :)

Hi all again! :)

I don't know if this is strcit a BEM question. Can I reuse just some parts of blocks?. Is a copy+paste thing and I think it's not a good idea.. :S

With this block

<div class="newsletter">
    <div class="newsletter__title">Newsletter</div>
    <div class="newsletter__subtitle">This is the newsletter subtitle</div>
</div>

Can I use just this in other parts of the interface:

<div class="newsletter">
    <div class="newsletter__title">Newsletter</div>
</div>

Or I need to create for example a modifier like newsletter--no-subtitle and hide it

<div class="newsletter newsletter--no-subtitle">
    <div class="newsletter__title">Newsletter</div>
    <div class="newsletter__subtitle">This is the newsletter subtitle</div>
</div>

Thanks you!!

Hi all! here I go again :) In the code below, how I should name the #### div?

I don't want to name it header__title because it doesn't reflect very well the DOM relation, and since BEM doesn't recommend nesting elements (And I don't really like too) it can't be header__rrss__title

So sorry for this silly question, I read all documentation FAQ's and I can't find any solutions :S

Thanks in advance,

F.

<div class="header">
  <div class="header__logo logo">
    <div class="logo__foo"></div>
  </div>
  <div class="header__rrss">    
    <p class="####"></p>  
    <div class="rrss-icons">
      <div class="rrss-icons__title"></div>
    </div>
  </div>
</div>

Hi all!

I've an issue with triple modifiers and I can't resolve without combine classes selectors :S. I have this button block:

<!--Button Block-->
<button type="button" class="button button--main button--outlined button--disabled">Ok</button>

and css (I remove some properties to save space in the post)

.button--filled,
.button {
  color: white;
  background-color: blue;
  box-shadow:none;
}

.button--main {
  font-size: 26px;
}

.button--outlined {
  background-color: transparent;
  box-shadow:inset 0px 0px 0px 4px blue;
}

Now I need a button--disabled modifier to shade to gray the button appeareance, but really I need two button--disabled because I need to shade to gray the border if button--outlined is used or the background if button--filled is used.

Do I need outlined and filled buttons in two separate blocks?

Thanks you! :)

Hello I am going through the quickstart tutorial. One of the first things I noticed on getting it running is that the HTML generated is all on one line. I am looking for a way to have it display in a readable way. I have looked at enb-borschik>techs>borschik.js and have tried commenting out: line 69: .defineOption('minify', true) line 85: minimize: this._minify, and restarted the server, but still seeing it compressed to one line. please let me know what to change to fix this. Thank You

So in my scss framework I define sizes gradually with a sass map with keys from xs to xxxl. So I can do things like creating button modifier classes from xs padding to xxxl padding in an each loop. In the case of a button it is pretty straight forward I have a button block class with a background color some padding and so forth. In the loop I create modifier classes looking like .button--xxl { padding: 2em; }. That makes sense - I have a base block class with all its stylings and I have a modifier class modifying a very specific aspect of the block class.

But now comes my "problem" - I have an .island block class which looks like this: .island { padding: 1.5em; } the modifier classes look like .island--xxl { padding: 2em; }. So the modifier class completely overrides the block class. In the case of the island class it may be a possibility to use a utility class instead - something like .u-padding-xxl { padding: 2em; }? But I have a second example:

.grid--spaced-horizontal {
  margin-left: -1.5em;
  > .grid__item {
    padding-left: 1.5em;
  }
}

.grid--spaced-horizontal--xl {
  margin-left: -2em;
  > .grid__item {
    padding-left: 2em;
  }
}

Again, it bothers me that the modifier class completely overrides the block class. I don't want to have <div class="grid grid--spaced-horizontal grid--spaced-horizontal--xl"></div> in my code when grid--spaced-horizontal is completely pointless.

What do you guys think about my problem? Am I completely on the wrong track?

Before (attempting) to use BEM, I'd mark my forms up something like this:

<form> 

    <h3 class="title">Form Heading <small>(if small tag is added)</small></h3>
    <p>Short paragraph of text...</p>

    <div class="form-group">
        <label class="label">Username <em>*</em></label>
        <div class="form-controls">
            <input type="text" />
        </div>
    </div>
    <div class="form-group error">
        <label class="label">Email address <em>*</em></label>
        <div class="form-controls">
            <input type="text" />
        </div>
    </div>
    <div class="form-group">
        <label class="label">Label</label>
        <div class="form-controls">
            <input type="text"  placeholder="" />
        </div>
    </div>
    <div class="form-group">
        <label class="label">Label</label>
        <div class="form-controls">
            <label class="radio"><input type="radio" name="radio" checked="checked" /> Option One</label>
            <label class="radio"><input type="radio" name="radio" /> Option Two</label>
        </div>
    </div>

</form>

It seems, obvious to use form__group instead of form-group and form__controls instead of form-controls. Using elements like this, the form would NEED a class of form on it - otherwise it makes no sense? Seems a bit strange on a default element though, I've not used <ul class="list"> for example, just <ul class="list--bordered"> for example.

I've created some quick, updated mark-up below, would this be acceptable?

<form class="form"> 

    <h3 class="form__title">Form Heading <small>(if small tag is added)</small></h3>
    <p>Short paragraph of text...</p>

    <div class="form__group">
        <label class="form__group-title">Username <em>*</em></label>
        <div class="form__controls">
            <input type="text" />
        </div>
    </div>
    <div class="form__group error">
        <label class="form__group-title">Email address <em>*</em></label>
        <div class="form__controls">
            <input type="text" />
        </div>
    </div>
    <div class="form__group">
        <label class="form__group-title">Label</label>
        <div class="form__controls">
            <input type="text"  placeholder="" />
        </div>
    </div>
    <div class="form__group">
        <label class="form__group-title">Label</label>
        <div class="form__controls">
            <label class="form__radio"><input type="radio" name="radio" checked="checked" /> Option One</label>
            <label class="form__radio"><input type="radio" name="radio" /> Option Two</label>
        </div>
    </div>

</form>

Thanks again!

Hi there,

I know one of the benefits of BEM is not having to nest styles but I was wondering when is it ok to do so? Sometimes it's unavoidable and sometimes maybe more practical to do so?

In the example I'm working on I have bands/stripes than contain blocks of content, these bands can be different colours (black, white, blue). I achieve this by having a base class of <div class="band">, which the band is black the following class is added: <div class="band band--black">. For obvious readability issues the content of a darker block will need to be coloured differently, the headings white, paragraphs/lists a lighter grey and maybe even a subtle lightening of the anchor colour. It'd be a pain to apply classes to everything, especially if different content mark-up appears on different pages. So is it acceptable to write the CSS like this (using SCSS):

.band--black {
    h1,
    h2,
    h3,
    h4 {
        color: rgb(255,255,255);
    }

    p,
    ul,
    ol {
        color: color: rgb(200,200,200);
    }
}

or even this, which might be able to keep track of, keeping the colour changes grouped together:

h1,
h2,
h3,
h4 {
    .band--dark & {
        color: rgb(255,255,255);
    }
}

p,
ul,
ol {
    .band--dark & {
        color: rgb(200,200,200);
    }
}

This is some (basic) sample HTML:

<div class="band band--dark masthead">
        <div class="wrap">

        <h1 class="masthead__title">Page heading</h1>
        <ul class="breadcrumbs">
            <li class="breadcrumbs__item"><a href="#" class="breadcrumbs__link" title="TITLE">Home</a></li>
            <li class="breadcrumbs__item"><a href="#" class="breadcrumbs__link" title="TITLE">Section Name</a></li>
        </ul>

        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut volutpat accumsan purus, in posuere nibh aliquam faucibus. Nam varius lectus id nunc ullamcorper, at euismod enim placerat.</p>

        <h3>Related Categories</h3>
        <ul>
            <li><a href="#" title="TITLE TEXT">Category 1</a></li>
            <li><a href="#" title="TITLE TEXT">Category 2</a></li>
            <li><a href="#" title="TITLE TEXT">Category 3</a></li>
            <li><a href="#" title="TITLE TEXT">Category 4</a></li>
        </ul>

    </div>
</div>

Another question I have is the class of masthead, part of me thinks this should really be band--masthead following the BEM spec?

Thanks in advance, just starting off with BEM so I keep find myself questioning most of my implementations of it!

The first example is strict bem, the second one less. Which of the following examples is more bullet-proofed (browser compatible, code readability, reusable etc.) :

<div class="block">
    <h1 class="block__headline">Headline</h1>
</div>

or

<div class="block">
    <div class="block__headline">
        <h1>Headline</h1>
    </div>
</div>

Hi,

I have a big disscusson with my colleague and would love to get your feedback.

I am building a website and have seen some areas, wich are reusable. They share the same HTML construct and looks similar. Example:

<header>
    <nav class="navigation navigation_main">
        <ul class="navigation__list">
            <li class="navigation__item"><a class="navigation__link">Item 1</a></li>
            <li class="navigation__item"><a class="navigation__link">Item 2</a></li>
            <li class="navigation__item"><a class="navigation__link">Item 3</a></li>
        </ul>
        </nav>
        <nav class="navigation navigation_meta">
            <ul class="navigation__list">
                <li class="navigation__item"><a class="navigation__link"><span class="svg-icon svg-icon_search"></span></a></li>
                <li class="navigation__item navigation__item_active"><a class="navigation__link">DE</a></li>
                <li class="navigation__item"><a class="navigation__link">EN</a></li>
            </ul>
    </nav>
</header>

My colleague says, that the navigations have to be named different:

<header>
    <nav class="main-navigation">
        <ul class="main-navigation__list">
            <li class="main-navigation__item"><a class="main-navigation__link">Item 1</a></li>
            <li class="main-navigation__item"><a class="main-navigation__link">Item 2</a></li>
            <li class="main-navigation__item"><a class="main-navigation__link">Item 3</a></li>
        </ul>
    </nav>
    <nav class="meta-navigation">
        <ul class="meta-navigation__list">
            <li class="meta-navigation__item"><a class="meta-navigation__link"><span class="svg-icon svg-icon_search"></span></a></li>
            <li class="meta-navigation__item meta-navigation__item_active"><a class="meta-navigation__link">DE</a></li>
            <li class="meta-navigation__item"><a class="meta-navigation__link">EN</a></li>
        </ul>
    </nav>
</header>

The navigations (there are some additional navigation in the footer and for social media icons, too) looks very similar. They differ in font size and paddings/margins. I see great advance in the first solution, because it is very modular and reusable. The end code is smaller. My colleague says, nesting (i.e. .navigation_meta .navigation__item{}) is evil and should be avoided, whenever possible (i.e .meta-navigation__item{}).

Who is right?

Hello,

I've adopted the directory organization where each block and element have their own directories. The problem with this apprach is that when I have a style like this:

.tile__icon-wrapper,
.tile__textual-part {
    display: table-cell;
    vertical-align: middle;
}

I do not have a choice but to repeat the same style definition in both tile__icon-wrapper.sass and tile__textual-part.sass.

Is there a sensible way to get rid of this redundant repetition and still adhere to BEM's principles?

Hey all!

I made a couple of silly, simple little snippets to detect improper usage of Elements and Modifiers.

Very simple, not necessarily failsafe or bulletproof, but a quick ’n’ dirty start. I need to DRY them out and roll them into one at some point as well.

The thinner the footprint the better.
Without all the heavy lifters like enb, only bem-tools maybe.

This is what I try:

npm install -g bem
mkdir bem-playground
cd bem-playground
bem create level my-blocks
bem create -b foo-block -l my-blocks -t <WHAT TYPE TO START WITH?>

html type is deprecated, list of types, I guess, is here: https://github.com/bem/bem-tools/tree/master/lib/techs/v2
Default types are empty so no block is created without -t.

Ok, I can create block manually. But what's next?
To assemble blocks into a page, I guess, I need some bemdecl and some assembler (enb again).
So I can't escape complexity footprint of enb onto my stack, right?

Can I mix Polymer and BEM (techs, tools, everything behind the methodology)? Does it worth it?

Ok, I've made a feature comparison table.
I need it to figure out if one technology can supplement another, not to downplay one of them.

Feature BEM Polymer
Syntax conventions (for B, E, M) yes no, use BEM
Decomposition into components ENB assembler (*) HTML Imports / webcomponents.js
# of requests reduction ENB assembler (*) vulcanize
CSS encapsulation upper boundary (*) upper boundary, lower for Native Shadow DOM (unstable)
Component redefinition yes, orginized in levels, ENB? (*) limited: extend native tags, inherit javascript definitions (behaviors), more is planned
File structure organization yes, B,E,M, techs no, use BEM
Techs support (templates, transpilers) yes server-side preprocessing (e.g. w/ gulp), client-side may be hindered

(*) = I guess so

There is an organisation on github called bem-incubator.

And this organisation is joined by more and more BEM community developers who uses BEM technology inside their projects and wants to develop technology together with us and maintain it together.

There are some recent projects:

  • ng-bem-components by @Guria — it's a wrapper that helps using bem-components on Angular. You can see how it works here.
  • enb-ng-techs by @Guria as well provides technologies ng-annotate and ng-templates to build Angular-powered projects with ENB.
  • bem-flux by @sameoldmadness — its realisation of FLUX paradigm for bem-core.
  • html2bemjson by @tadatuta allows converting HTML code to BEMJSON. New version of the package was baked recently.
  • @awinogradov baked major release bem-grid 2.0.0 in the frames of which grid has moved to using lost.
  • bem-scrollspy by @kompolom — its realisation of scrollspy on i-bem.js.

If you have useful tools and libraries based on BEM technologies, join our BEM incubator!

Here are some latest links that we have found on the topic:

  • React BEM helper by Marco Hamersma (@marcohamersma) from Berlin.
  • BEM classnames by Hayato Mizuno (@pocotan001) from Tokyo.
  • React BEM by Cuzzo Yahn (@cuzzo) from LA.
  • bem-cn from Alexander Burtsev (@albburtsev) from Moscow.
  • b_ by Mikhail Davydov (@azproduction) from Berlin.
  • Flexible Grid System BEM CSS by Doğukan Güven (@dnomak) from Turkey.
  • A PostCSS plugin to lint BEM-style CSS by Nicolas Gallagher (@necolas) from San Francisco (Twitter) and David Clark from Turkey.
  • BEM Constructor by Daniel Guillan (danielguillan) from Barcelona. It's a Sass-library that gives you syntax sugar to describe independent objects in BEM style.
  • _bemify — Sass mixens that help you to write .scss in BEM style, by Franz Heidl (@franzheidl) from Berlin.
  • Front-end Elements Dictionary or a set of popular naming for classes in BEM style by Vladimir Rodkin from Saint Petersburg.
  • GETFLAT — demo project build on Angular-BEM + LESS and Gulp by Vladimir Titsky (@catindev) from Karaganda.
  • bnsf framework by Alexander Savin (@apsavin) migrated to ENB build.

Add yours in comments!

There was a thread recently in Russian on using BEM in medium-sized projects written by Nikolay Gromov who complained that writing BEMJSON requires more time than writing HTML with a help of emmet.

I don't feel the same way about time spent on writing code not in percentage relating to time spent on debugging and thinking over not in absolute terms but I thought that spending time for writing analogue for emmet for BEMJSON is good enough task to spend an evening.

It is how this package bemmet emerged that can expand abbreviations like b1>__e1*2>b3_theme_islands+_state_active{hello} into BEMJSON:

{
    block: 'b1',
    content: [
        {
            block: 'b1',
            elem: 'e1',
            content: [
                {
                    block: 'b3',
                    mods: { theme: 'islands' },
                    content: {}
                },
                {
                    block: 'b1',
                    mods: { state: 'active' },
                    content: 'hello'
                }
            ]
        },
        {
            block: 'b1',
            elem: 'e1',
            content: [
                {
                    block: 'b3',
                    mods: { theme: 'islands' },
                    content: {}
                },
                {
                    block: 'b1',
                    mods: { state: 'active' },
                    content: 'hello'
                }
            ]
        }
    ]
}

Using options you can configure custom naming — powered by bem-naming. stringify() method supports indentation options and quotes — powered by stringify-object.

You can try bemmet in action using online demo. You can also install it right away into your editor using plugins for Sublime Text and Atom.

Would be nice if you can commit with plugins for some other editors.

Good luck!

I was wondering why you chose to define an element entirely using classes in the HTML instead of breaking shared functionality into placeholders / mixins (to use Sass as an example). Is it because you don't use a preprocessor?

If we take the example of a list, it might look like:

<ul class="ui-list horizontal-list resource-list gallery-list"></ul>

In this situation, why is this better than a single class:

<ul class="gallery-list"></ul>

With that class composed from placeholders:

.gallery-list {
  @extend %ui-list;
  @extend %horizontal-list;
  @extend %resource-list;

  // Gallery List specific styles
}

Do you see this as potentially beneficial?

What is the correct way of naming items in a list when the item itself has subcomponents. Is it the case that the item should be classed both as a child block of the list and as its own component? Is the following example correct?

<div class="news-feed">
  <h3 class="news-feed__title">…</h3>
  <ul class="news-feed__list">
     <li class="news-feed__list-item news-feed-list-item">
        <h4 class="news-feed-list-item__title">…</h4>
        <img class="news-feed-list-item__thumbnail">
     </li>
  <ul>
</div>
  1. Any well-known websites use BEM, other than Yandex?
  2. In BEM, each block on a page has their own css file, would this increase the page loading time?

Many thanks!

Добрый день,

Подскажите пожалуйста как производить навигацию между страницами. Так сложилось что мне сначала нужно зайти на url для авторизации и потом зайти на другой где собственно уже и производить тест. Пытался найти есть ли возможность работать в gemini с навигацией в браузере из коробки. Как я понял нету, т.к. в кол бэк возможно передать только actions и find/ Вторым вызовом suite.setUrl() поменять урл на другой не вышло. С нестед сьютами так же не выходит. Возможно я не так их применял ниже код:

parent.setUrl('first url') .setCaptureElements('element'); gemini.suite('first child', function (child) { //this suite captures same elements on different pages child.setUrl('secondUrl') .capture('plain'); Заранее спасибо за любую помощь.

Question from https://github.com/fabm22: Hi, is there some tooling for checking the structure of CSS code following BEM approach and having and some warnings if there are errors? Thanks a lot

I am large

.button {border-radius:5px;}

As you see in the example above i have a block named "button". I want to reuse the block "button" inside another block "button-group".

However when a button is used within a "button-group" block i would like to apply some slight modifications.

  • The left button should have radius only on the left.
  • The middle button should have no radius.
  • The right button should have radius on the right only.

How should I do this? The straight forward way for me would be:

.button-group .button {border-radius:0;} .button-group .button:first-child {border-left-radius:5px;} .button-group .button:last-child {border-right-radius:5px;}

Thanks

1. Naming convention

In terms of convention we used to use dashes as word separators, two underscores to separate elements and one underscore for modifier and it's value:

  • block-name
  • block-name__some-elem
  • block-name_mod-name_mod-value
  • block-name__some-elem_elemmod-name_elemmod-value

But it worth nothing to use any other style. We even have special library to abstract from naming.

More about naming convention: https://github.com/bem/bem-naming#custom-naming-convention

2. Going beyond naming convention

Naming convention is important but UI component is more than just a piece of CSS.

All methodologies for CSS could be considered as a subset of BEM. But they tell nothing about how to implement other pieces: JS, templates, images, specs, documentation (and its translation to different languages), etc.

BEM as methodology does.

3. Component approach

Actualy it's not something absolutely unique nowadays. We already have Web components as a standard speaking almost about the same:

  • Split interface into independent blocks
  • Each block knows everything about itself and hides it's inner implementation
  • Declarative way to describe components

All these questions are solved in BEM without any polyfills. But what's much more important all these things are easy to use and tested in production on a lot of services with a really huge scale (in all sences of this word).

4. What's inside

4.1. DOM abstraction

DOM is too low level thing. It's like an assembler for browsers. We need to provide developers with high level abstraction. In BEM it's called BEM tree.

CSS and JS implementation of the block and it's templates work with it's elements. And for other blocks we provide API to work with.

So instead of waiting for shadow DOM roots to grow we just use current DOM tree for inner implementation of components.

4.2. Mixes

Mixes is a concept of having few different entities on the same DOM node. That gives a possibility to separate semantically different code:

<div class="header__user user link"> — it's simultaneously user element of a header block, user block itself and also a link to use profile.

4.3. File system

Each block get's it's own folder. And all techs of the block — their own files. Modifiers and elements may also be separated into different folders to provide possibility to build just the parts files we need.

Example:

blocks/
    b1/
        b1.css
        b1.js
    b2/
        __elem1/
            b2__elem1.css
        b2.css
        b2.js
        b2.en.md
        b2.ru.md
        b2.spec.js
        b2.png

4.4. Build

BEM tree works as a declaration to build final runtime upon.

Example:

Consider following BEM tree:

<page>
    <b1>
        <b1__e1>
   </b1>
</page>

or the same in JS:

{
    block: 'page', content: {
        block: b1, content: {
            elem: 'e1'
        }
    }
}

Now we can collect all the entities mentioned in this declaration to get all the files from block folder and concat them together.

4.5. Levels of redefinition

With such approach we can build entire library of components for all the purposes (and we actualy did ;)

But it's impossible to meet all the needs. So end users will face situation when they need to change something. Of course they always may edit the source of the library, add modifiers and mix new blocks to old ones to make them look and work as they need. But first option result in a pain when you are to update library version and others require quite a lot of efforts.

But because of declarative nature of blocks implementation we can just put our code in our own block folder and ask build system to concat files from there after library files:

library/
    blocks/
        b1/
            b1.css
                .b1 { width: 100px; color: red; }
project/
    blocks/
        b1/
            b1.css
                .b1 { color: green; }
    pages/
        page/
            page.css
                @import url(../../../library/blocks/b1/b1.css);
                @import url(../../blocks/blocks/b1/b1.css);

So we end up with b1 which is still 100px wide as in library but is green according to our company guidelines.

Absolutely the same approach is used for JS and templates. So developer may get some levels (layers) from a list of block libraries, decide which levels are needed for particular project, then add some specific code on project's level and update source libraries as easy as run bower update.

5. Implementation

At Yandex we implemented and open sourced a full stack of tools written in node.js to work with BEM methodoly as well as JS framework (it uses jQuery under the hood) and template engines operating in BEM terms and some block libraries on top of it.

Quite a lot of companies in CIS in addition to Yandex are already using it and we can confidently say there's no interface tasks which can not be splited into blocks-elements-modifiers.