Login with github
  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.

Hi, some time ago jQuery team asked us about BEM, and we cleared a lot of points for them. Answers are quite useful, so we decided to publish them free.

1. How easily is BEM kept maintainable long term?

Easy maintenance is what BEM was invented for.

Actually all the issues with CSS maintenance are because of cascade and strong coupling of components. And BEM is all about independence of blocks and reducing cascade to minimum level.

We have a lot of real experience with BEM on our portal and it proved to be a great solution.

Example 1.

ul a {
    position: absolute;
}

won't work as soon as you'll get second level of nesting for lists.

Example 2.

Considering menu can't have any other list items:

ul.menu li {
    ...
}

and then some components with own dropdown with own menu appear in list item.

2. The long class names can come off a bit intimidating and unfriendly for beginners using BEM. What is the justification behind the longer names? As it is now, we already have many people complaining when we use ui-button for a class name instead of btn, because the former is too long.

Well, BEM does not restrict usage of btn instead of button ;) You can consider any naming strategy you want. E.g.: context or ctx or c, attributes or attrs or as.

The choose is yours — BEM doesn't srink you.

There is still some "problem" with elements and modifiers, i.e. btn__txt and btn_hvrd, but we strongly believe that there's no real problem in typing. And of course there's no problem with kilobytes due to gzip. But what is really important for huge rapid projects which live for a long time is code readability and self-descriptive names of components is just a must.

Not so cool for common block library with a huge amount of users.

3. The namespacing decisions in general - members of our community would like a greater explanation of this.

That was something odd when we invented BEM. But right now that's a common idea: OOCSS, Atomic CSS, etc. and web components standard try to hide internal world of a block from other ones. Web components use shadow DOM, BEM uses namespacing to achieve the same result but without necessity to wait for support from browsers or any additional JS.

Historical reason of having namespaces for modifiers is that joined selectors like .a.b were not supported in old browsers. Not it's not a restriction but in BEM there's also a concept of mixes — possibility to have a few different entities on the same DOM node. And namespaces help to distinguish modifier of which block is it.

Without mixes it's possible to have .btn._hvrd but we are sure that mixes are useful thing.

But what is often left in shadow is possibility to mix different entities on the same DOM node. E.g. it's possible to have <input class="input form__login"> which means we've got an input block (can be reused somewhere else) and login element of form block at the same time. So everything about abstract input will be provided by .input selector and things like margins, etc — with .form__login.

4. Neutering the Cascading potential of CSS code by making everything overly specific.

Yes, that looks strange at the first sight but soon you'll find it very convenient. Cascade is cool for fast write-and-throw-away approach. But when we need bullet proof reusable components it just doesn't work.

Cascade creates strong coupling and results in impossibility to reuse such code.

5. The arbitrary distinction between blocks and elements.

Let's look at JS (actually OOP) analogy. JS class point [x, y] is just a field of Figure class or one more class Point. If it has a lot of methods it's most likely a class by its own. Otherwise field is enough. The same is for blocks and elements. It's always for your consideration.

With practice that's easier than it looks. When an entity is impossible without its parent — that's an element. When you find yourself trying to reuse an element somewhere in a project without its parent and inner complexity of element became bigger — that's a standalone block.

But what is often left in shadow is possibility to mix different entities on the same DOM node. E.g. it's possible to have <input class="input form__login"> which means we've got an input block (can be reused somewhere else) and login element of form block at the same time. So everything about abstract input will be provided by .input selector and things like margins, etc — with .form__login.

In the simplest form a block is represented by a single DOM node but generally blocks and DOM nodes are not the same thing.

Mixes are just the way to use several blocks and/or elements on the same DOM node.

That makes possible

  • combining behaviour and/or styling of different BEM entities without copy/paste
  • building new semantic components based on existed blocks.

For instance, we have a universal block logo (a block with a logotype) that could be used anywhere on a page: in header, inside copy, in the footer, etc. We can specify its width, height and a background image but what we do with its margins that differ from case to case?

Of course, we could use modifiers like logo_type_header or logo_type_content to do so. However it is wrong semantically, because such things should lay down within a scope of parent block’s responsibility. And giving the right to define such things to an inner block contradicts the whole idea of blocks independency.

That's where mixes shine:

<div class="header">
    <div class="header__logo logo"></div>
</div>
.logo
{
    width: 120px;
    height: 60px;
    background-image: url(logo.svg);
}

.header__logo
{
    margin: 12px 26px;
}

As you know there's no global modifiers in BEM methodology but again — mixes gives us possibility to achieve the same result with several different blocks on same DOM node.

Also you may want to use mixes to provide some arbitrary block with JS logic.

A single DOM node can represent:

  • several blocks <div class="menu head-menu"></div>
  • a block and an element of the same block <div class="menu menu__layout"></div>
  • a block and an element of another block <div class="link menu__link"></div>
  • elements of different blocks <div class="menu__item head-menu__item"></div>
  • a block with a modifier and another block <div class="menu menu_layout_horiz head-menu">
  • several different blocks with modifiers <div class="menu menu_layout_horiz head-toolbar head-toolbar_theme_black"><div>

So try to develop your blocks as small and reusable as possible and then combine them in any way you want to build huge applications!

Hello.

Today there has been a BEM workshop in our company (SC5 Online, Helsinki, http://sc5.io/) We studied basics like CSS approach and modular file structure. People did their tasks one by one "at the stage" :-) These are the slides, and the task is inside http://varya.me/bem-css-workshop/

Finishing the tasks we could compare the changes we provided without BEM in mind https://github.com/varya/bem-css-workshop-source/pull/1/files and with BEM https://github.com/varya/bem-css-workshop-source/pull/2/files In my mind, it shows the different very clearly and it is easier to understand the idea of BEM. Even better than presentations and the articles.

BTW, I was surprised to learn that many don't know about BEM selectors supporting in SASS and LESS although this is at least 1-year-old feature.

How is it in your mind? Feel free to use slides.

Recently we learnt that cascade term was used wrongly all the time. Spec: http://www.w3.org/TR/2009/CR-CSS2-20090908/cascade.html#cascade What are you going to do with wrong usage of this term in this website? For example Max uses it here https://en.bem.info/articles/bem-for-small-projects/#bye-bye-cascade-4 And so do I in this article https://en.bem.info/articles/yandex-frontend-dev/ And I guess in many places all over the website.

Hi everyone,

We are ready to launch our BEM forum — a place where developers working with BEM can get together, share their experiences and ask questions directly to the BEM team.

Little bit of history

We wanted to have our own communication platform for a long time.

Before we launched BEM forum on bem.info for Russian language community in August 2014 we had to monitor a lot of social media platforms such as twitter, Yandex blog platform, facebook, in order not to miss your questions.

At the same time Yandex was shutting down it's blog platform, and that decision forced us to launch the forum.

We carefully planned it, have chosen github to host everything as well as to login through and we went live as well as moved in to github 5 years of blogging history that we wanted to keep.

We were worried from the beginning that useful channels of communication will still prevail, and developers continue to ask questions everywhere and not here that is time consuming in terms of search and not usefull at all for archiving the history for the sake of future users.

But forum proved us wrong: the number of posts grew up every month, and it is about 40 posts (issues) per month now.

Inside the forum

As we do almost everything in open source, forum is an open sourced platform too. This means we encourage you to use it in your home projects and report bugs.

The repository could be found here. Local copy installation instruction is in it's readme file.

Forum's architecture allows using it well as a separate service and as a route for express. We use it in a second capacity — it is a part of bem.info site.

We use github API as a source of data, node.js for backend and full stack of BEM (BEMTREE, BEMHTML, i-bem.js) for frontend.

Right now it is possible on BEM forum to open a topic, comment it and filter posts using labels. We already made few necessary for you there. And if you lack one or have a question regarding the work of the forum, just open a topic and mark it with "bem-forum" label.

Every post is an issue on github that we browse on the site. This scheme allows communicating via forum having what developers already have — github login.

Attention: we ask you to use our forum via bem.info interface, because here you can have it labeled and found by others.

All you need to start using BEM forum is to authorize via oAuth using your github login.

Start writing your first post right now! We as a BEM team and guys from the community monitor user questions all the time and answer them right away.

We also hope you open our eyes on the problems English language developers have with BEM (anything from documentation to demos, from installation to use cases). Just mark such posts with "bug" label. It will be a lot of a help!

Let's get started with BEM forum!