Menu Search
Jump to the content X X
Smashing Conf San Francisco

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf San Francisco, dedicated to smart front-end techniques and design patterns.

A New Front-End Methodology: BEM (File System Representation For A Block)

BEM stands for “Block”, “Element”, “Modifier”. It is a front-end methodology: a new way of thinking when developing Web interfaces. This article will elaborate on the theory as well as the practice of building websites at Yandex—one of the leading internet companies in Russia.

Due to the length of this article, it was split into three parts:

Unequivocal Placement of Code

File Naming

When a project is:

  • Long-lived and under constant development.

If the development team:

  • Consists of several people.
  • Grows and changes.

Then being able to navigate the code base quickly is crucial.

Block code is easiest to find when it’s placed in files using the same naming scheme as the one we use for naming our entities:

Expressing Blocks on a File System

There could be a task:

  • To reuse some blocks from a previous project for a new one.

We want the procedure of block reuse to be as simple as possible—like simply copying the files, or using partial checkout of a repository from a “donor” project. In both cases, it is useful to have all of the files under the same directory:

File Structure of a Block

When working on a project we might need to change a block at some point.

A manager could ask:

  • To change the color of the Current Menu Item, or
  • To make the Menu react on hover.

A developer could ask their colleague:

  • To help with Search Form styling for IE.

To understand where the relevant code is located, follow these (or similar) rules:

  • Block code is placed in a separate directory.
    • Directory name matches block name.
    • Implementation is placed under this directory.
  • Elements are placed in subdirectories under the block directory.
    • Directory name matches element name.
    • Implementation is placed under this directory.
  • Modifiers are placed in subdirectories under the block directory.
    • Directory name matches modifier name.
    • Implementation is placed under this directory.
    • File name includes both key and value of the modifier (again, for programmatic access).


File structure of a Menu block:


Maintaining such file structure manually is, quite obviously, inconvenient. So we’ve developed BEM Tools3 to handle the burden. These tools help with creating the directory structure, placing files, generating placeholder content, etc.

Grouping Blocks in Directories

Big internet portals often need to reuse the same blocks across different websites.

There could be a task:

  • To create the same Footer on all the portals’ websites, or
  • To create a new project using blocks from the existing websites.

Working for a Web design agency often means that one has to use typical solutions for typical Web pages.

A project manager could ask you:

  • To create an order page with a Web form as on the previous project.

We have to do these tasks while preferably avoiding copying blocks around manually. So it’s nice to have a repository of shared blocks that can be linked to a project. Blocks should then be united under a single directory for that.

Such a directory is usually called Blocks.



That directory can be linked to another project straight from the version control system, so that we can make changes to shared blocks in a single location.

Levels Of Definition

If a group of blocks (united under one directory) is linked to a project directly (via a partial checkout, svn:externals, etc.), then every change committed to these blocks influences all projects.

When developing a website based on an existing one, we might want:

  • To enlarge the font in the Head on site A without affecting site B.
  • To add animation when showing a drop-down menu.

To do so, we need to be able to define or redefine blocks in different technologies for a specific website only, or for certain pages only. This can be achieved using Definition Levels.

A Definition Level is a set of blocks grouped in one directory.

An implementation of every block from the library can be changed (or completely redefined) at project level.

block levels4

From page-building process’ perspective:

  • When building a page, we can set a list of levels (directories) to use their blocks on that page. E.g., build-page -l blocks-common -l blocks-my my-page.html

From the file structure point of view:

  • A project can have any number of levels. But only the levels that are evaluated during the build will be present on the page. It is possible to specify different sets of definition levels for different parts of the website.

On the JavaScript side:

  • We need to define dynamic behavior of a page in declarative style. Final behavior is gathered from different definition levels. E.g.,
/* blocks-common/dropdown/dropdown.js */
Block('dropdown', {
  init: function() {

/* blocks-my/dropdown/dropdown.js */
Block('dropdown', {
  init: function() {

From the viewpoint of a template engine:

  • To be able to not only define, but to redefine a template, one needs to apply a preceding template implementation.
    E.g., for XSL:
<xsl:template match="b:head">
  <div> <!-- Node for extra design -->

From the architectural point of view:

  • When developing a portal of several websites, we can extract a block library that serves as one of the definition levels for all the websites which are part of the portal. The blocks for a specific website will form another level.
  • The same repo can hold blocks of both desktop and mobile versions.
    Such a project will have the following levels: common, mobile, desktop. Different combinations of these levels give the resulting implementation, required by specific pages.

Open source block library bem-bl (in development)5 is an example of having several definition levels in one repository.

Building A Page

Working in terms of blocks means having a Subject-Matter Abstraction. This abstraction is for developers only, and browsers will get a compiled version of the code.

So we have Code For People and Code For Browsers—they are not the same.

  • Programmers code blocks—browsers get the code for the whole page.

To turn Code For People into Code For Browsers we Build a page.

Building A Page means generating HTML, CSS, and JavaScript code from a page declaration (written in XML or JSON) by applying implementations of declared blocks.

On the CSS side:

  • All CSS files are combined into a “single page” CSS file.
    Despite the fact that CSS for every block, element or modifier is stored in separate files, we don’t have to link these files to the page as is. It’s possible to collect all the required CSS implementations into one file.
    This also solves the well-known “number of imports” issue in IE, and decreases the number of HTTP requests. For combining CSS we use borschik146.
  • Browser gets minimized code.
    When building CSS, we can minimize and optimize CSS code using the CSSO357 utility, for example.
  • Each browser can get CSS code written especially for it.
    It is also possible to divide CSS implementations for different browsers and deliver only the code needed for each browser.
    setochka—currently in prototype8 can be used for that.

From the JavaScript point of view:

  • Similarly to CSS, JavaScript files can be combined into one.

From the template engine’s point of view:

  • Only needed templates are included.
    Final set of templates that are used for displaying a page includes only the templates for required blocks. This boosts template performance and reduces the likelihood of side effects.

From the viewpoint of development process:

  • Robots serve people (not the other way around).
    Developer writes code as they see fit. “Robots” take (some) care of performance by optimizing the code (together with making it unreadable) when building a page.

In terms of work organization:

  • Division of labor.
    We have developers working on the core framework (compilers, tools, performance); library developers, who maintain the block library; application developers, who develop websites using the framework.

We use BEM tools9 to build pages.

How to Automate the Building Process?

The usage of bem tools10 requires to run several commands for each page whenever page input data or blocks implementation are changed. As a result of these commands, you get CSS and JavaScript files for the page, page’s template, and if you are developing static pages, the HTML code of your page.

To avoid running these commands manually, there is also the GNUmakefile11, which was written for a project that includes the instructions on how to build pages.
You can find an example of such a file in the test project bem-bl-test12.

But the usage of GNU Make has a list of problems:

  • You have to run it every time you have changed something.
  • Every time you run gmake, it reads the information from a disk. So the compilation process could not be fast.
  • The pages you build not only depend on the content of block files, but on their file structure as well. But it’s impossible to write a gmake goal dependency in these terms.

So we’d like to create something to replace GNU Make for the process of page building. This will be both a development server and a tool to build production files. Bem Server will be run in a project root directory, and give HTTP response with the page files built (so you won’t need to run gmake manually after each change).
Besides, it will be able to watch the files (the adding and removing of them) via fs.FSWatcher that help to chache results efficiently.

BEM Server is a subcommand of bem-tools13. Currently it can run an HTTP server, apply BEMhtml templates to BEMjson data and inline CSS imports using borschik146 utility.

Real Examples

Yandex15 is a large (mostly Russian) company that use BEM methodology to develop its services.

BEM methodology does not request that you use a certain framework. You also don’t have to use BEM for all the technologies you have on your pages (but that would be the most efficient).

All the services of Yandex16 have BEM in their CSS, JavaScript code or XSL templates for their pages. E.g.,

Some services don’t use XSL templates, building their pages with our newest template product, Bemhtml template engine which was mentioned above. These are the following services:

There are also other companies that use BEM methodology.

For example, the guys at Mail.ru24 partly use BEM for their services. Some blocks on their pages are BEM-based in terms of CSS code. They also have their own C++ template engine, and write block templates according to this methodology.

More examples:

You also may be interested in websites that use bem-bl28 block library (in development):



Additional Information

Smashing Special: A Three-Part Article

Due to the length of the article, it was split into three parts:



  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17;sll=37.609218%2C55.753559&amp;ll=37.609218%2C55.753563&amp;spn=2.570801%2C0.884460&amp;z=9&amp;l=map
  18. 18;rpt=image
  19. 19
  20. 20
  21. 21
  22. 22;lr=213
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38

↑ Back to top Tweet itShare on Facebook

I am a front-end developer working for Yandex since 2008. Now being a team-leader of development an UI framework (CSS/HTML/JavaScript + templates) for building Yandex-style sites, I'm also pushing some internal front-end technical solutions into Open Source.

  1. 1

    I am interested but skeptical. Javascript templating is great but this seems like unnecessary encapsulation for the sake of creating block objects. For example, on Yandex Maps I was just scanning the source and found this link:

    a class=”b-link b-link_is-bem_yes b-link_type_metro i-bem b-statcounter__item b-statcounter__item_clickable_yes b-statcounter__item_path_metro” …

    That is a mouthful for one little link. DRY coding practice might suggest that b-statcounter and b-link should be abstracted further up the cascade.

    At the end of the day it comes down to time and cost. How much money does BEM and bem-tools save Yandex annually versus a different templating framework or writing vanilla styles with the same BEM principles?

  2. 2

    Anthony Madhvani

    April 17, 2012 2:44 am

    I’m not entirely sure wether this methodology is nessecary on all but the biggest of websites. I know virtually nothing about BEM, but I could see the amount of overhead becoming monstrous fairly quick. I wonder if there is a point at which it defeats its actual purpose, i.e. preventing duplication and streamlining development. It would be interesting to say to least to see how the amount of abstraction impacts the development process. Either way, it is nice to see that there is renewed interest in front-end methodologies. I think I will just stick with my own slightly modified version of SMACCS for now, though.

  3. 3

    Nick Gassmann

    April 17, 2012 11:55 am

    I was right there with you until you started modularizing the files and folder structure. That just looks like a major headache. What’s wrong with simply commenting your code and breaking it up there?

  4. 4

    Roman Komarov

    April 18, 2012 3:37 am

    See that comment by Leonid —

    The BEM in file system is great for big projects or frameworks. And the modules are great for code reuse — even for small projects it’s easier just to copy reset.css, typography.css, grid.css etc. from the previous project, then trying to find all the needed styles in the one big stylesheet.

  5. 5

    Val Kotlarov Hoffman

    April 17, 2012 10:36 pm

    Great article!
    It’s a great deed to abstract components from the whole (webpage). I would like to get a deeper insight into this. The reason is that I had similar thoughts about bringing Component Object Model/OOD into the web with all the consequent meanings of that – like incapsulation, polymorphism (well, inheritance – suppose if I want to take a button, and inherit from it by adding another properties like borders or colors etc..). My bet that this paradigm is better suited for the big websites, but on another perspective – reusability is also great for the smaller dimension fields, e.g. web design companies etc. Does BEM support this? Thanks.

  6. 6

    Vitaly Harisov

    April 18, 2012 4:05 am

    Block implementation is mix of multiple technologies, not a single one. Block styles, images, scripts, templates and documentation – it’s all block technologies and it’s all stored in the directory which represents block in the file system. The same is true for the elements and modificators.

    Our point of view is that block is primary and technologies it is implemented by are secondary. That’s why at first we separate blocks in file system and then add all needed technologies step by step.

  7. 7

    Vitaly Harisov

    April 18, 2012 4:06 am

    Modularizing is to build different sites from the same blocks. If you go to some Yandex sites, you’ll see that they have some similar interface objects (blocks). They are slightly different (mostly in appearance) but have a lot of in common.

    Yandex is a portal of 150 sites and that’s wrong and expensive to copy&paste pieces of code about all interface objects which are the same. Especially if your CSS code is in one place, JavaScript is in another and so on. Again, there should be a possibility to change those objects at all the projects.

    So, having all (CSS, JavaScript, templates, documentation) about one block in its folder enable us to link this block to a new project. That is by linking a folder via svn:externals, by copy & paste block’s folder automatically (with tools) or manually.

    Since blocks on different sites are similar but not the same, we should redefine them a bit. So, the is a concept of levels. We have our internal library of more than 100 blocks which are one level. And every project can have its own level to slightly change blocks. That works for all the techs: CSS, JavaScript, templates.

    Having a reusable code library is also useful for web-design agencies to save their time.

  8. 8

    David Trindade

    April 18, 2012 4:27 am

    I was kind of liking it until about halfway the second part – by the end it had completely alienated me.
    (I’m only into the HTML/CSS and Jquery side of front-end dev)

    In my view it’s too much abstraction and too many different technologies to make it work – and I can only see something like this working alright in massive portals.
    The other 95-99% of projects out there would probably suffer from all the hassle having to set all the files, dependencies and modules to make it work.

    Not for me at all.

  9. 9

    Sergey Berezhnoy

    April 18, 2012 8:20 am

    If I understand you correctly, by “this” you mean incapsulation, polymorphism and inheritance. This is what BEM think about that:

    Incapsulation happens by design. Every block can be used as a part of another more complex one. Thanks to unique CSS classes and avoding Tag Selectors, you are free to include any block into another.

    Polymirphism happens by 2 reasons. First, there are modifiers. They are to slightly change block appearance or behaviour. Besides, there are definition levels which enable you to use a set of block from a common library (first level) and slightly redefine them at your project (second level).

    Inheritance is possible via polymorphism. You can have something basic and then some specific cases inheriting. Also there is a “mixin” term in BEM. Two or more blocks and element can be placed at teh same DOM node. Mixins are successfully used in many programming languages as a way to reuse basic code.

  10. 10

    Vitaly Harisov

    April 20, 2012 4:40 am

    There is no restriction in the methodology. Only dividing a page into blocks, elements and modifiers. You can use as much from the methodology as you wish (not only a full stack). Toolkit is flexible to support that.

    The simplest case is using BEM in CSS when you mentally divide your page into blocks but use one CSS file (as usually):

    /* head */
    .head { … }
    .head .logo { … }

    /* foot */
    .foot { … }
    .foot .copyright { … }

    But when including one block into another elements can be affected (by cascade). In this case elements of one block are indiscernible from another’s (if those elements have the same CSS class). Again, you cannot tell apart a block and an element.

    With that in mind, we came to a rule that element’s name is including a block which element belongs to.

    /* head */
    .head { … }
    .head__logo { … }

    /* foot */
    .foot { … }
    .foot__copyright { … }

    The scheme “block__element” is not strict, its only our internal naming convention. You can use another naming and tune bem-tools in accord with your scheme.

    When you have many blocks in those one CSS file, you’ll like to divide it into pieces. So, you can have a CSS file for every block. The final (page’s) CSS file can be build manually or with a utility.

    .head { … }
    .head__logo { … }

    .foot { … }
    .foot__copyright { … }

    @import url(head.css);
    @import url(foot.css);

    If you need a place for pictures, it can be the same where CSS files are:



    Then, your project is grownig. There are a lot of blocks. And some new technologies are coming up (javascript, templates, documentation) Since then block directories became handy:



    Again, you can use as much from the methodology as you wish.

  11. 11

    Wow! Thank you so much for sharing these concepts. I have been thinking a lot lately how html, css and js are still very intrinsically coupled, especially when you need to cater for older browsers (I’m lookin at you IE). For example, you can code html to a high semantic level, but when it comes to achieving a certain look, you are forced to add html elements to get there.

    I really like your ideas of concentrating on what you are setting out to achieve first, then breaking it into the smallest divisable pieces (your blocks) then combining the tchnologies you need to achieve it.

    I can see that many people will soon begin creating ther own bem libraries to share with the world. It’s great!

    I do have a couple of questions though. How do you incorporate a content management system into this concept? How does dynamic content get injected into the BEM templates?

  12. 12

    I have to say it’s really a promising project. As a back end developer, I really love this idea to modulize the front end. I will take time to go deeper and feedback about this project.

    Thanks the great article and your sharing to us :)

  13. 13

    Alex Yaroshevich

    September 16, 2012 9:14 am

    As far as I know if your CMS can produce text output (like HTML or something) — you just need to divide all of your data and all your view. There is no place to template engines like Smarty, Twig, etc. because their template files contains both: html and data output. BEM methodoly works like a charm but needs data divided from view. The best examples here are xml for data + and xslt for representing data in html, bemjson (data) + bemhtml (for html). But web here is just a little part of all possibilities.

    For example you have a simple page with 2 blocks encapsulated to 1 page block. These 3 blocks have 3 different views. Page block is static but 2 other blocks are generating for users differently. And when your system getting request to show some page you deciding which blocks need to show. All needed blocks must be included to resulting page structure: page { block1, block2 }, page { block2 { block1 } }, or any other version.

    In other words any CMS can easily produce pure blocks of data in some specific format. And then all of that blocks just combining one to another… to big structure of concrete page. Resulting structure contains all data needed to draw page to html and you just need to put the whole page to render page view. Anywhere. Even in console or mobile device if you have render for that.

    Just now you operating with blocks. Nothing more. It’s simple and beautiful.

  14. 14

    I’m really digging this whole BEM methodology. I accidentally discovered it while moving away from bootstrap (which is really just a style guide) and trying to architect a larger site on my own. There is one addition I’m gonna make in my own projects though: I will separate “Page Level Blocks” from “Element Wrapper Blocks”. I’ve been reading into SMACSS as well, and there he has a “Layouts/” folder. I think it makes sense to put page level blocks there. Then in my BEM “blocks/” folder, I’ll put the element level blocks.

    Also, for the element level blocks, I kinda feel like these should almost always be DIVs. You can certainly attach classes to forms, ul, p, etc…but I feel like the block is the container/division and that’s usually a div. However this leads to the dilemma of having too many divs! Another thought that just came to me is that forms and uls are really containers so I could probably see them as element level blocks rather than elements themselves…but then again according to html5, these should most likely be wrapped in a *section* element, so the section or div is really the block(?). A little confusing, but would really like to hear your response. Thank you for a wonderful system.

  15. 15

    John Slegers

    July 10, 2013 5:06 am

    I love OOCSS, but I’m not very fond of BEM. While OOCSS leads to shorter, more efficient, more elegant and more reusable CSS code, BEM does de exact opposite.

    First of all, I see no valid reason to distinguish between blocks and elements. Why should there be two types of elementary building block when you could just have one type?

    Also, it makes no sense to use selectors like “.menu__item” instead of “.menu .item” or “.menu > .item”. It makes your HTML code more convoluted, it adds bloat to your CSS and it restricts reuse of shared CSS rules.

    The same is true for modifiers. Why use “.menu_size_big” and “.menu_type_buttons” when you could use “.menu.big” and “.menu.buttons” or even “.menu .big” and “.menu .buttons”? Why must the modifiers be so overly restrictive?

    Consider the following syntax for a basic navigation element :

    <ul class=”nav “>[ … ]</ul>

    Different types of navigation could be defined by wrapping this element in a div with a functional modifier :

    <div class=”menu”><ul class=”nav”>[ … ]</ul></div>
    <div class=”tabs”><ul class=”nav”>[ … ]</ul></div>
    <div class=”tags”><ul class=”nav”>[ … ]</ul></div>

    An additional modifier can be used to adjust the orientation (where relevant) or further refine the behavior :

    <div class=”menu”><ul class=”left nav”>[ … ]</ul></div>
    <div class=”tabs”><ul class=”bottom nav”>[ … ]</ul></div>
    <div class=”menu”><ul class=”tree nav”>[ … ]</ul></div>
    <div class=”tags”><ul class=”blocks nav”>[ … ] </ul></div>

    Functionality shared by all navigation elements can then be defined using the “.nav” selector.

    Functionality specific to a navigation type can be defined using selectors like “.menu .nav”, “.tabs .nav” or “.tags .nav”.

    Selectors like “.left” and “.tree” (or “ul.left” and “ul.tree”) can be used to define behavior for different nagivation types that share the same orientation or specific behavior.

    Such an implementation keeps both the CSS code and HTML code very DRY, is supported by older browsers (including IE6) and provides endless possibilities with regards to combining different elements / blocks.

    See for a CSS framework based on that strategy.

  16. 16

    Imran Bughio

    August 9, 2013 6:02 am

    BEM pretty hard to start with, till now i used simple HTML, SASS and some jquery to do all my front end work, but when i try to jump on BEM, i get all these new terms like Node.js, NPM, GIT, Bash, Shell, SUDO, etc. Thou i did installed all these stuff but got stuck on bem server for some reason its giving a HTTP 500 error and does not complies BEM Jason files in to HTML….. is there a proper guide out there on where to start and how to setup BEMHTML on Windows! or any place i can discuss technical issues?

  17. 17

    how about css sprites? i usually have a few large spritesheets containing all sorts of icons, etc. this BEM thing seems to enforce using separate images instead


Leave a Comment

You may use simple HTML to add links or lists to your comment. Also, use <pre><code class="language-*">...</code></pre> to mark up code snippets. We support -js, -markup and -css for comments.

↑ Back to top