A New Front-End Methodology: BEM

Advertisement

This article is the sixth in our new series that introduces the latest, useful and freely available tools and techniques, developed and released by active members of the Web design community. The first article covered PrefixFree1; the second introduced Foundation2, a responsive framework; the third presented Sisyphus.js3, a library for Gmail-like client-side drafts, the fourth shared with us a free plugin called GuideGuide4 and the fifth presented Erskine Design’s responsive grid generator Gridpak5. Today, we are happy to feature a toolkit devised by Yandex: BEM.

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:

BEM Principles

To begin, let’s first put BEM in some historical perspective.

We first began sketching out the internal front-end framework at Yandex around the year 2007, starting with a robust CSS naming convention, and a file system layout that was associated with it. Since the naming convention was well-structured, it seemed suitable to develop certain JavaScript helpers (to work with the DOM and CSS classes in particular, on a higher level of abstraction). We then used those approaches to build an internal library of UI components that could be shared among our various websites and rich applications, built using different technology stacks (XML/XSLT, Python/Django, Perl/TT2).

As our ambitions, complexity and performance requirements grew, we aimed at replacing XSLT and Perl templates with a JS-based declarative templating DSL, built on top of Node.js. Along with those efforts, we looked into simplifying development workflow and developed a bunch of command-line tools that already helped us manage front-end code on the file system, preprocess CSS and JavaScript code, and so on, and so forth.

Some parts of the BEM stack started as open source projects, while others (like the UI component library) are being gradually open sourced. Our goal is to publish most of them during 2012.

BEM is a toolkit that will help address and resolve front-end issues quickly and effectively. It is available in a range of reusable code libraries—all of them are hosted on Github and are completely open source.

BEM Principles

One of the most common examples of a methodology in programming is Object-Oriented Programming. It’s a programming paradigm embodied by many languages. In some ways, BEM is similar to OOP—a way of describing reality in code, with a range of patterns, and a way of thinking about program entities regardless of the programming languages being used.

We’ve used BEM principles to create a set of front-end development techniques and tools that allow us to build websites quickly and maintain them over a long period of time. The principles are the following:

Unified Data Domain

Imagine an ordinary website, like the one pictured below:

ordinary website example8

While developing such a website, it’s useful to mark out “blocks” from which the website consists of. For example, in this picture there are Head, Main Layout and Foot blocks. The Head in turn consists of Logo, Search, Auth Block and Menu. Main Layout contains a Page Title and a Text Block:

site marked9

Giving each part of the page a name is very useful when it comes to team communication.

A project manager could ask:

  • To make the Head bigger, or
  • To create a page without a Search form in the Head.

An HTML guy could ask a fellow JavaScript developer:

  • To make Auth Block animated, etc.

Let’s now take a closer look at what constitutes BEM:

Block

A block is an independent entity, a “building block” of an application. A block can be either simple or compound (containing other blocks).

Example
Search form block:

search form block10

Element

An element is a part of a block that performs a certain function. Elements are context-dependent: they only make sense in the context of the block that they belong to.

Example

An input field and a button are elements of the Search Block:

elements of search block11

Means Of Describing Pages And Templates

Blocks and elements constitute page content. Besides simply being present on a page, their arrangement is also important.

Blocks (or elements) may follow each other in a certain order. For example, a list of goods on a commerce website:

list of goods on a commerce website12

…or menu items:

menu items13

Blocks may also be contained inside other blocks. For example, a Head Block includes other blocks:

blocks inside other blocks14

Besides, our building blocks need a way to describe page layout in plain text. To do so, every block and element should have a keyword that identifies it.

A keyword designating a specific block is called Block Name. For example, Menu can be a keyword for the Menu Block and Head can be a keyword for the Head block.

A keyword designating an element is called Element Name. For example, each item in a menu is an element Item of the Menu block.

Block names must be unique within a project to unequivocally designate which block is being described. Only instances of the same block can have the same names. In this case, we can say that one block is present on the page twice (or 3, 4, times… etc.).

Element names must be unique within the scope of a block. An element can be repeated several times. For example, menu items:

repeated elements15

Keywords should be put in a certain order. Any data format that supports nesting (XML, JSON) will do:

<b:page>
  <b:head>
    <b:menu>
      ...
    </b:menu>
    <e:column>
      <b:logo/>
    </e:column>
    <e:column>
      <b:search>
        <e:input/>
        <e:button>Search</e:button>
      </b:search>
    </e:column>
    <e:column>
      <b:auth>
        ...
      </b:auth>
    <e:column>
  </b:head>
</b:page>

In this example, b and e namespaces separate block nodes from element nodes.

The same in JSON:

{
  block: 'page',
  content: {
    block: 'head',
    content: [
      { block: 'menu', content: ... },
      {
        elem: 'column',
        content: { block: 'logo' }
      },
      {
        elem: 'column',
        content: [
          {
            block: 'search',
            content: [
              { elem: 'input' },
              {
                elem: 'button',
                content: 'Search'
              }
            ]
          }
        ]
      },
      {
        elem: 'column',
        content: {
          block: 'auth',
          content: ...
        }
      }
    ]
  }
}

Examples above show an object model with blocks and elements nested inside each other. This structure can also contain any number of custom data fields. We call this structure BEM Tree (by analogy with DOM tree).

Final browser markup is generated by applying template transformations (using XSL or JavaScript) to a BEM tree.

If a developer needs to move a block to a different place on a page, he does so by changing the BEM tree. Templates generate the final view themselves.

In our recent products we went with JSON as a page description format. It is then turned into HTML by a JS-based template engine. The tools we use are listed at the end of this article.

Block Independence

As projects grow, blocks tend to be added, removed, or moved around on the page. For example, you may want to swap the Logo with the Auth Block, or place the Menu under the Search Block.

swapping blocks

To make this process easier, blocks must be Independent.

An Independent block is implemented in a way that allows arbitrary placement anywhere on the page—including nesting inside another block.

Independent CSS

From the CSS point of view it means that:

  • A block (or an element) must have a unique “name” (a CSS class) that could be used in a CSS rule.
  • HTML elements must not be used in CSS selectors (.menu td) as such selectors are inherently not context-free.
  • Cascading selectors for several blocks should be avoided.
Naming for Independent CSS Classes

One of the possible naming schemes for CSS classes that satisfies said requirements is the following:

  • CSS class for a block coincides with its Block Name.
<ul class="menu">
  ...
</ul>
  • CSS class for an element is a Block Name and an Element Name separated by some character(s)
<ul class="menu">
  <li class="menu__item">
    ...
  </li>
  <li class="menu__item">
    ...
  </li>
</ul>

It’s necessary to include block name in a CSS class for an element to minimize cascading. It’s also important to use separators consistently to allow the tools and helpers to have unambiguous programmatic access to the elements.

Different naming schemes can be used. Take a look here16 for the naming convention we used.

Independent Templates

From the template engine’s perspective, block independence means that:

  • Blocks and elements must be described in the input data.
    Blocks (or elements) must have unique “names” to make things like “Menu should be placed here” expressible in our templates.
  • Blocks may appear anywhere in a BEM tree.
Independent templates for blocks

When coming across a block in a template, the template engine should be able to unambiguously transform it into HTML. Thus, every block should have a template for that.

For example, a template can look like this in XSL:

<xsl:template match="b:menu">
  <ul class="menu">
    <xsl:apply-templates/>
  </ul>
</xsl:template>

<xsl:template match="b:menu/e:item">
  <li class="menu__item">
    <xsl:apply-templates/>
  </li>
<xsl:template>

We are gradually discarding XSLT in our products in favor of our own JavaScript-based template engine XJST17. This template engine absorbs everything we like about XSLT (we are fans of declarative programming), and implements it with JavaScript’s productivity on either the client or the server side.

We, at Yandex, write our templates using a domain-specific language called BEMHTML, which is based on XJST. The main ideas of BEMHTML18 are published in the BEM club on Ya.Ru (in Russian).

Smashing Special: A Three-Part Article

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

(jvb)

↑ Back to topShare on Twitter

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

    While I am completely behind the basic idea of BEM for creating modular code that is ready to be used with a proper dependency system I get the feeling that half of this article is centered around countering it’s own hacks.

    Why on earth would you use a naming convention for css classes that includes the name of the parent as well if you also recommend using a css preprocessor, which can easily scope your css very precisely? Furthermore this magic preprocessor apparently assumes that it should strip the name of the parent selector from the nested selector. Why?
    Elements are perfectly selectable without doubling up on class names. Heck, for the example given, just selecting by the block class name and html structure below that without any classes would be enough.

    Furthermore the article recommends hacking in an ‘elem’ function into jQuery that has the same functionality of mangling the selector based on this weird naming of css classes. jQuery has a perfectly fine .find() method in case you aren’t just selecting by decendency in the first place directly in the jQuery selector.

    And now suddenly this css class naming hack finds its way into the file structure as well. Why is that? Why should relations between blocks and items be described through hackish naming conventions and hierarchies instead of through proper description of dependencies between files?

    Simply put, what problem is it these hacks are trying to solve?

    1
    • 2

      Leonid Khachaturov

      April 16, 2012 10:15 am

      > Why on earth would you use a naming convention for css classes that includes the name of the parent

      It’s not as simple as that. Describing that “this element belongs to that block” is not the same as describing the parent-child relationship. Remember that an HTML element could be marked as a BEM block and as an element of a different BEM block simultaneously.

      > Elements are perfectly selectable without doubling up on class names

      Sure. They are perfectly selectable without any class names too. The point is, we want them a) efficiently and b) unambiguously selectable.

      > And now suddenly this css class naming hack finds its way into the file structure as well. Why is that?

      First, it’s about size and complexity. The in-house version of the library has around 100 blocks, a typical project built upon the library has 50 more. I doubt we’d be better off dumping all of the CSS files into a single directory. Second, there are tools. When I’m describing a page I’m including a certain block and a certain modifier of it, I don’t want the rest of them included in the built CSS (JS). Hence the fine-grained splitting of “stuff” into many small files. But it’s not like you *must* use the described layout, it’s just a description of what Yandex does at their scale, the whole thing can be downscaled as much as one wishes.

      0
  2. 3

    Ну наконец-то разродились постом для Смешинга! :)

    It’s really cool methodology and we use it in all of our projects. I can’t even imagine how to write complicated markup without BEM.

    0
  3. 4

    Read this article the other day from the BEM GitHub page.
    Very insightful!

    @KingScooty

    0
  4. 5

    Mihail Yakimenko

    April 16, 2012 8:51 am

    This methodology good for team worked on a big projects, like Yahoo, and Yandex, or may be Bing. Also Yahoo have same methodology.. but in everyday, every, simple site, or not simple, NOT usable!!! Because^ whay i should learned new code? html5 css3.. and BEM-json…??? Why? :) Sorry, better if i learned jinja2, or jango, ruby, templates, this is more in demand!!!

    0
    • 6

      Of course, BEM is not a panacea. And you should know the reason for using it. But BEM is useful not only for large portals. BEM method gives your code accuracy, precision and structure.

      Use it if:
      1) A project is to maintain it in the long run. If code has order, you’ll pick it up after a long time and remember easily.

      2) A team is 2 or more developers. With BEM it’s possible to assign new members to a team without a steep learning curve. Again, code has order, and that enable you to avoid spaghetti.

      3) Projects are fast-to-develop. They all are different but in accord with the same scheme. The idea on ‘levels’ enable you create a library of reusable code. That’s useful not only for large portal but for web-design agencies also.

      0
      • 7

        Mihail Yakimenko

        April 17, 2012 2:40 am

        hmm.. As I said, Bam is not well everywhere. Bottom line: too highly specialized metodlogiya.

        Some are much easier to understand than the manner, the structure semantic of html5 BEM. Front-end developers must have knowledge about html5 semantic!

        But I’m not saying that the BEM is bad. I say unaffordable. Any way.. Good Luck!!!

        0
      • 8

        I like the ideas, and I will use them in my own implementations (albeit a modified version since I’m not building yandex or any of its sites), however, I have one nagging question. Why use element modifiers? for example, for a menu you have: b-menu, b-menu__item, b-menu_bg_red?? So let me guess, you want to re-use b-menu in say the footer, but don’t want a red background? ok, so if I want a large text, I’d do: b-menu_text_large? how about inline styling? is that a block modifier or an item modifier? Because what if I want my header menu to display inline while secondary left menu display as a vertical list. lemme guess: b-menu__item_layout_inline? b-menu__item_layout_vertical?? Please let me know your thoughts, but this seems like over-kill to me. I’d just target based on where I am. #left .b-menu__item {display:block;} // #head .b-menu__item{display:inline-block;}

        0
  5. 9

    Looking forward to the following articles. We have a similar system of building blocks (we call it component-based), but I think there are still some substantial differences. Interested to see how this develops.

    0
  6. 11

    In relation to Blocks as a concept, it’s worth noting that the FOSS CMS Concrete5 has used this paradigm since its first release: http://www.concrete5.org

    0
  7. 12

    It’s a nice approach, but it’s your implementation of the Composite pattern I think, rather than a ‘new methodology’.

    0
  8. 13

    I don’t like this, but I may just be misunderstanding it. It looks like you’re just reinventing the DOM because you don’t have a templating system that lets you do partials / sub templates. The DOM Is already a tree, and with partials you can move things around just as easily, without this abstraction. Your template could be ” {{ nav }} {{ header }} ” and you could just as easily change it to ” {{ header }} {{ nav }} “. boom. done. no extra step.

    0
    • 14

      First, BEM tree is next abstraction. And with that in mind DOM becomes “Assembler”. That allows to express much more than using pure DOM only.

      A designer doesn’t draw DOM element in their PDS files. You usually get a set of interface objects from which your site consist of. BEM tree enable you to represent these object without thinking of their DOM implementation.

      One DOM node can contain one BEM block or one BEM element. But you can also mix BEM entities using the same DOM node. You can place 2 (or more) blocks in one node, or mix blocks and elements.

      For example, there is a custom input block implemented in a library “form-input”. And you need to extend its functionality with something (maybe tag filters or suggestion) since your input is now a part of a special search form. Then mix “search__request” element with “from-input” at the same DOM node and you’ll get what you need. There is no need to change something in “form-input” functionality (its even wrong because then your “from-input” block unable to be copy&paste to another page or project), just write it for “search__request” element.

      The block can be mixed with its own element as well. The element of the block can be outside the block in DOM but to be block’s part mentally and from the point of view of JavaScript.

      The block can also be on 2 (or more) DOM elements. That’s quite difficult example so it’s not included in the article.

      The JavaScript code we provide enable you to work with all those cases without thinking where the blocks and elements physically (in DOM) are.

      0
      • 15

        Are you saying that a “BEM” node implies CSS and javascript functionality too? So including a node will somehow include a javascript block? or am I missing what you’re saying?

        I still don’t get how it’s any nicer than just moving around block calls in a regular old template.

        0
        • 16

          Varvara Stepanova

          April 20, 2012 7:06 am

          All block technologies work together. That doesn’t mean that JavaScript is inline HTML. But JavaScript of the block is linked to a page when necessary.

          It takes time to explain how it works. I think we should write another article about that.

          I don’t know yet where such an article may be published. But you can join to BEM group in Facebook (http://www.facebook.com/groups/209713935765634/), we will announce all the text there.

          0
  9. 17

    Gunnar Bittersmann

    April 16, 2012 11:56 pm

    I liked the first part of the article – the visualization of blocks and page elements.

    I disagree with the second part, though.

    In a list it is of little help to give each ‘li’ element a class “menu__item”. To do so is “classitis”, not reasonable HTML code. The list items are marked-up as such already – by their element type ‘li’. In CSS, you can select them with ‘.menu li’. That’s what type selectors and descendant combinators are for. So use them!

    “HTML elements must not be used in CSS selectors” is a bad advice. “[…] as such selectors are inherently not context-free” – so what? With ‘.menu li’, you still have an independent template for the menu and its items.

    0
    • 18

      > In CSS, you can select them with ‘.menu li’. That’s what type selectors and descendant combinators are for. So use them!
      Ok. Next time you’d need to include ordered list into an unordered one. And whoa, .menu li applies to the new list as well. And you can’t just redefine it with single class like modifier.
      This simple case shows how such a “simple” approach leads to specificity hell. There are more complex cases in the wild and they’re reducing developing speed and flexibility. Working with such code takes a lot of extra time and efforts. I don’t want for example extra margin-left when I’m inserting unordered list into a header in WordPress.

      0
      • 19

        Gunnar Bittersmann

        April 17, 2012 3:51 am

        > Next time you’d need to include ordered list into an unordered one. And whoa, .menu li applies to the new list as well.

        OK, if you’re gonna style just first-level list items, you would select only those: ‘.menu > li’.

        > And you can’t just redefine it with single class like modifier.

        Sure you can. You could overwrite the styles for lower-level list items by selecting ‘.menu li li’.

        The approach to give every element a class seems to come from folks who are unaware of the possibilities that CSS has to offer.

        0
        • 20

          Varvara Stepanova

          April 17, 2012 5:11 am

          > Sure you can. You could overwrite the styles for lower-level list items by selecting ‘.menu li li’.

          This case you need CSS changes every time if something changes at your page. With a large project and a large team that can happen without you know the fact.

          0
        • 21

          Surely you can use .menu>li, but imagine sometime you’d need to add header, thus you have to switch from ul to something else like SECTION>Hn or reorganize in such way that “menu” class goes to parent element. With BEM you need only to change HTML and it just works. When you are depending on structure you have to make changes in CSS as well.

          0
          • 22

            Gunnar Bittersmann

            April 17, 2012 8:18 am

            Varvara wrote:
            > This case you need CSS changes every time if something changes at your page.

            Yeah, sure. That’s a benefit, not a drawback.

            GreLI wrote:
            > you need only to change HTML

            HTML changes are not “only”; CSS changes are. You just change one CSS file instead of many HTML files. Or even worse, server-side program logic that generates HTML ressources.

            0
        • 23

          Frederik Krautwald

          December 5, 2012 9:16 pm

          > You could overwrite the styles for lower-level list items by selecting ‘.menu li li’.

          This doesn’t work in favour of selector performance. CSS gets evaluated from right to left, which is why Google Page Speed Recommendations regarding efficient CSS selectors state: “Avoiding inefficient key selectors that match large numbers of elements can speed up page rendering.”

          To sum it up what is considered inefficient:
          * Rules with descendant selectors. E.g., ‘.menu li’
          * Rules with child or adjacent selectors. E.g., ‘.menu > li’
          * Rules with overly qualified selectors. E.g., ‘ul.menu > li’
          * Rules that apply ‘:hover’ to non-link elements. E.g., ‘li.menu-item:hover’

          Of course, by using child selectors, you can limit the DOM traversal. But in the case you mention you can’t use ‘.menu > li > li’ and so on, so what you get is a factorial increase in the traversal the deeper the level.

          0
    • 24

      Varvara Stepanova

      April 17, 2012 3:00 am

      There are several reasons why we chose such a naming convention.

      The main is reflow time. Browsers parse CSS rules from right to left. That means, that selector “.menu a {…}” browsers apply that way: 1. Select all ‘a’ nodes of the page. 2. Filter that ‘a’ nodes and keep only those of them that has ‘.menu’ as ancestor.

      If you have two or more rules ending with “a” (.menu a {}, .head a {}, .sumenu li a) a browser would try to apply every rule to every link of the page. That could slow your page rendering speed, as it takes a lot of excess time.

      Since we got know about that аrom the article https://developer.mozilla.org/en/Writing_Efficient_CSS#How_the_Style_System_Matches_Rules and video presentation http://www.youtube.com/watch?v=a2_6bGNZ7bA (draw your attention on the 15th minute) we made our own research that proved the fact.

      That’s why we create our blocks and elements independent by setting them unique CSS classes to avoid cascade. And it works, our web mail page became 10 times faster, after such an optimizations.

      One more reason is independence itself. Having a cascade ending with “li” or “a” you cannot guarantee that won’t affect descendant blocks. Since the blocks we are producing able to be combined as you wish (e.g. next day a block may be included into another one) we need avoid side effects.

      0
      • 25

        I think it would be nice to make a description of the benefits in the article itself about the BEM

        0
      • 26

        Selector performance for “.menu a” and “.menu li” should be more than adequate for most projects. And in those ultrarare cases where that might not be enow, “.menu .item” and “.menu .link” or “.menu > .item” and “.menu > .link” would be much cleaner alternatives.

        Still, avoiding selectors ending with “a” or “li” inevitable leads to HTML bloat that could do more damage than good in the long run. Having your HTML filled with classes that exist only for that reason sounds like a suboptimal strategy for performance tweaking.

        “.menu .item” also provides more flexibility and independence than something like “.menu_item”. If you have a “.checklist” or “.tabs” list where items share some of the rules, your strategy requires the same rules to be repeated for “.menu_item”, “.checklist_item”, “.tabs_item” and any other list that where items share those same criteria.

        If I go with “.menu .item” instead, I can put all shared code in the “.item” selector. New list types will automaticly inherit that shared code when I include the “.item” class to its list elements. Yet, I can still put all code specific to a certain navigation type by using selectors like “.menu .item” and “.tabs_item”.

        Finally, the very strength of CSS is to allow cascade. Preventing it makes no sense and shouldn’t be necessary if you design your blocks/elements well. See http://cascade-framework.com/ for how to make optimal use of the cascade.

        0
    • 27

      Varvara Stepanova

      April 17, 2012 3:25 am

      I can also provide test examples:

      1) 30 000 div nodes at the page. Selectors for them end with “.text”
      http://vitaly.harisov.name/example/perf-test-classes1.html?reflow-meter
      That is 5 seconds of reflow time.

      2) 30 000 dive nodes, but selectors end with “div”
      http://vitaly.harisov.name/example/perf-test-classes2.html?reflow-meter
      Be careful! Your browser can get frozen for a while.
      That is 37 seconds.

      The more Tag Rules you have for your page, the slower is its rendering.

      0
      • 28

        Don’t know what browser you use, but in Chrome I got 208ms for the first page and 484 ms for the second.. hardly 37 seconds ;)

        0
        • 29

          In Firefox 11 I got 1989 ms for the first page and 18245 ms for the second.

          In Opera 12 — 1336 ms and 14297 ms.

          In Safari 5.1.5 — 178 ms and 307 ms.

          0
          • 30

            Well I guess that means that Chrome is awesome and if you have 30 000 div nodes, then you are doing something really wrong :)

            I do understand your point though, we all know now that it’s not efficient to write: div.class a { } when you have a lot of ‘a’ nodes, but I think the point is not to use it when you don’t need it – if you have 30 000 nodes then you need it..

            0
        • 31

          “but I think the point is not to use it when you don’t need it – if you have 30 000 nodes then you need it..”

          The example with 30 000 nodes is synthetic, however the difference in reflow can be significant if you’re animate something — 100ms can matter.

          Also, in modern web Apps a big number of nodes is not something rare — take the Twitter, Facebook or any other site where there is an infinite list of entries — with each new pack of entries the DOM grow bigger and bigger, and the reflow time grows as well. And if you’d then try to animate the whole page, you could get a freeze :)

          0
      • 32

        In my browser ( Win 8 + Chrome ) it took 429 ms to process the first example and 203 ms to process the second example, which are results similar to those of Victor Schelin.

        Victor was also right to point out that needing to process 30000 div nodes is something most of us are unlikely to ever do in a real life situation, making it a very artificial example.

        What makes it even more artificial, is that the test uses descendant selectors with 4 levels of descendance. 4 levels of descendance are rarely a good idea. If you can’t restrict yourself to 2 or 3 levels, you should consider an ID based selector. That will have far more radical performance improvements than anything you’re trying to achieve here.

        Finally, let’s consider the following :
        * The file using the selectors ending with “.text” has a size of 593 826 bytes
        * The file using the selectors ending with “div” has a size of 589 829 bytes
        * That size can further by reduced to 563 829 bytes by dropping all the unnecessary “text” classes

        While that is only a difference in size of 5%, the application of BEM logic across an entire website will result to far more bloat than 5%, especially compared with a more basic OOCSS architecture.

        Based on all these arguments, I expect that in many cases BEM will actually result to worse performance rather than better performance.

        0
  10. 33

    Great concept, thanks for this! Even as a webdev newbie, i can see the advantages , especially for working in a team, or for big, long projects, as well as for a quick set up of a project.

    And now something completely different: LOVELY sketches !!!!

    0
  11. 36

    Nice lengthly and useful post.Thanks for sharing.

    0
  12. 37

    Christian Nascimento

    April 17, 2012 3:08 am

    Apparently, it’s a great concept. Thanks for sharing!

    0
  13. 38

    “A block (or an element) must have a unique “name” (a CSS class) that could be used in a CSS rule.”

    The whole point of classes is to group elements, not denote something unique. If the block element truly is unique, you use an id attribute.

    “It’s necessary to include block name in a CSS class for an element to minimize cascading.”

    So BEM wants to take the cascading out of Cascading Style Sheets (CSS)? OK…?

    “HTML elements must not be used in CSS selectors (.menu td) as such selectors are inherently not context-free.”

    As far as rendering performance goes, this is a good idea. However, it sounds like the developer doesn’t have confidence in the HTML they have written, meaning that it could change and therefore you need to avoid using this so that the CSS won’t have to be altered.

    The frontend developer should be writing clean semantic and flexible HTML, then it won’t really matter what element you’ve used, it would be the CSS that needs to be altered instead of the HTML. The structure of the document should reflect its content, not altered to fit the presentation.

    Sounds like BEM builds on some fundamentally unsound principles that fly in the face of front end web development paradigms.

    The authors may think they’re in a class of their own, but the rest of us call that an id.

    0
    • 39

      Varvara Stepanova

      April 17, 2012 5:16 am

      > The whole point of classes is to group elements, not denote something unique. If the block element truly is unique, you use an id attribute.

      Elements don’t need to be unique. There could be 2 or more same elements inside a block. “Unique” here means they are unlike elements of other blocks. The second element can appear at any time (when a task is changed), so we avoid using id attributes.

      > So BEM wants to take the cascading out of Cascading Style Sheets (CSS)? OK…?
      Yes, it is so. And the reason also is that “unique” classes are much faster. I explained that here: http://coding.smashingmagazine.com/2012/04/16/a-new-front-end-methodology-bem/#comment-577298

      0
      • 40

        Gunnar Bittersmann

        April 18, 2012 12:47 pm

        > And the reason also is that “unique” classes are much faster.

        You go for highest performance but you use jQuery instead of plain JavaScript? Now that’s – em — funny.

        “For most web sites, the possible performance gains from optimizing CSS selectors will be small, and are not worth the costs.” http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

        0
        • 41

          Varvara Stepanova

          April 19, 2012 2:49 am

          > You go for highest performance but you use jQuery instead of plain JavaScript? Now that’s – em — funny.

          Using jQuery is only an example. BEM doesn’t order to use a particular framework. You can use your own. We don’t use those jQuery methods which are slow.

          0
          • 42

            Using jQuery instead of vanilla JS is likely to negatively impact your performance more than you can ever gain from optimising selector performance.

            Also, going for “unique” elements will only cause more bloat (both in your HTML and CSS) because of the forced code repetition for shared rules, while neutering your CSS code by reducing one of its greatest strengths : the power of the cascading mechanism.

            0
      • 43

        >”Yes, it is so. And the reason also is that “unique” classes are much faster. I explained that here:”

        Faster rendering (for slow GPUs/CPUs? Targeting phones?) in exchange for larger HTML. Since CSS is cached while each HTML page needs separate loading, it sounds like a trade-off.

        I have seen these pages, with many many wrapping elements each with a class on them. They weren’t particularly snappy loaders, and the code-to-content ratio was pretty high. I’m thinking at that point, it made more sense to make things easier for the developers (for reasons listed in the article and comments) who are more expensive than hardware, than to try to create the least amount of code to get the job done.

        This reminds me of when CSS grids came out. Developers really liked the change in their workflow when using them.

        0
  14. 44

    BEM (my nickname, which stands for Bernadette Emsenhuber)

    April 17, 2012 4:12 am

    … and i’m not a front-end methodology

    0
  15. 45

    It’s always amazing to see how mankind takes something pretty simple and makes a bloated mess out of it.

    0
  16. 46

    looks way over the top for me. I use rails with HAML and SASS which is way more unobtrusive than this approach.

    Why reinvent the wheel? Seems totally over engineered to me…

    0
    • 47

      Varvara Stepanova

      April 17, 2012 5:18 am

      BEM enable us to use any technology we want. It’s a group of principles and a way of thinking. Replacing CSS with SASS changes nothing. The same for CoffeeScript instead of JavaScript.

      0
  17. 48

    I really like BEM and oocss, smacss, etc.). But I think small websites don’t need this approach. It just depends. If you are working on a large scale application like a complex portal you REALLY benefit from reducing complexity by building modular blocks. You can never ever be sure how html will be build. There will be gazillions of developers messing around with html and wrapping “unique” blocks into each other. Selecting with element tags will cause a lot of sideeffects.
    To all those “experts” here. Start working on a big project and you will see why methods like BEM exist. It’s not about clean html and semantics. It’s about efficiency, scalability and maintainance. Btw. SASS is just a tool. It doesn’t replace profound knowledge of frontend coding paradigms.

    Some people here asked why we should use BEM (or similar methods): It’s because CSS has some fatal faults like scope. There is no scope in CSS. Just the cascade. Selecting with the cascade and element tags == using global variables. It will cause side effects. That’s why we use “hacky” workarounds like namespacing with classes and building unique and independent blocks.

    0
    • 49

      OOCSS significantly reduces the required amount of CSS rules to build a website and provides optimal code reuse while also offering improved flexibility.

      BEM does the opposite. It adds bloat to both CSS and HTML while reducing flexibility and code reuse.

      0
    • 50

      I work on such project and completely agree with you. Our application is comprised of various modules and components. Once you start scoping things, the selector becomes ridiculous. In addition, any developer can look at my component/selector and know exactly where it lives in our code base.

      BEM has been really helpful for our team.

      0
  18. 51

    Very insightful and explained in detail… may become messy but I see a good use case for maintaining the code for future. I will definitely try to use it and recommend this to my peers.

    0
  19. 52

    Andreas Köberle

    April 17, 2012 10:49 pm

    After all, this is the way GWTs UiBinder work: https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder

    0
    • 53

      Sergey Berezhnoy

      April 20, 2012 4:12 am

      You are right, GWTs UiBinder does the same if we are speaking about connection between CSS, HTML and JavaScript. They are parts of widgets. But unlike GWT, BEM doesn’t require Java or another particular implementation. BEM is mostly a method. You can use its principles for your current projects in any language. Including those languages which will be born only tomorrow :-)
      I can also mention that UiBinder is in GWT since version 2.0, but BEM became earlier.

      0
  20. 54

    No disrespect intended whatsoever to the author, but I just can’t fathom more frameworks or methodologies or any other abbreviated tech at the moment.

    With HTML5, CSS3, jQuery, Responsive Design, Mobile Design, User Interface, Frameworks, Code Hacks, Polyfills, Media Queries, Browser Compliancy Testing and the myriad of what feels like a billion other areas of progressive web design, I’m pretty much just burnt out on learning something new.

    At the moment, I’m just not able to tread water with having to learn all these things. We really seems to have what feels like a needlessly complex amount of technologies; or maybe I just feel like I need to master every single one of them.

    0
    • 55

      Leonid Khachaturov

      April 18, 2012 10:43 am

      Well, that’s the essence of this profession – you have to learn and relearn all the time. Yeah, maybe some fields are more “established” than the others but it’s the same everywhere, from Enterprise Java to hipster HTML5 :)

      0
  21. 56

    Thanks for BEM. We are using it in all our projects.

    0
  22. 57

    I like the style of coding, in fact it is quite similar to a ZenCoding, which would be like BEM-on-the-fly. But well structure. I will certainly remember some principles used in here. Also, I couldnt help notice that you mentioned:

    “Blocks may appear anywhere in a BEM tree.”

    If I understood your concept well, blocks cant appear inside of elements. Please clarify.

    0
    • 58

      Varvara Stepanova

      April 19, 2012 2:51 am

      Sure, you can combine blocks as you need. A block inside another one is possible. A block inside an element is possible too.

      0
  23. 59

    “It was as if its architects were given a perfectly good hammer and gleefully replied, neat! With this hammer, we can build a tool that can pound in nails.”

    0
  24. 61

    I’m confused… why is it that you think people should learn a different language, when there is already one that works quite well? It’s called HTML.

    0
    • 62

      Varvara Stepanova

      April 20, 2012 4:33 am

      Have you read the article? :-) BEM is not a new language. Sure, all the pages are written in HTML.

      0
  25. 63

    I agree that BEM it’s not a remedy for everything, but it definitely makes your work easier in many cases.

    0
  26. 64

    I’ve been doing this for a long time. Infact, I have techniques that are ahead of these. The language you use and the naming conventions you apply makes all the difference. At this stage, your naming convention will get you thus far. For example, items that are actually “Content Elements” f.e. you call text and picture presented as a single component a “Block”; which you also give to a Search component. Later down the road, you will have problems separating the two, and it will become a bad learning experience which leads to painful coding. Best way to code is to call them what they are.

    0
    • 65

      I totally agree with you. This is how even I do my Web pages.

      It’s important to understand the redundancy of content at the design level itself. Sometimes, Designers come up with fancy menu designs or gradients, then client demands to provide support for features like, WordPress 3 menu system for example. Then it becomes a real time-consuming challenge for JavaScript, CSS and HTML coders to come up with some sort of redundancy that may work fine inside a program Loop accommodating unspecific number of content items.

      “Call the blocks what they are” is a perfect point you’ve made here my friend. This way, you can name the blocks and see repeating them… see if you’ve any conflicts. If no conflicts, you can safely start with CSS and block arrangements, soon you will find using the same Block and content names as CSS Class and ID for those blocks in actual HTML. People who follow this style, found HTML5 exciting and something that goes in tune with how they think while converting image designs into real HTML, creating a base for dynamic database driven programming.

      0
  27. 66

    oh so everything is going modular?

    0
  28. 67

    You say: An element is a part of a block that performs a certain function. In this case I don’t understand why the columns in the example are defined as elements and not as blocks. Can you explain?

    0
  29. 68

    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 http://cascade-framework.com/ for a CSS framework based on that strategy.

    0
  30. 69

    Give a try to “dress-and-drink HCJ framework”: https://code.google.com/p/dress-and-drink/

    It combines html template, css template,javascript template into a single HCJ template on the client side.

    0
  31. 70

    This sounds a whole lot like the general concept surrounding Web Components, which is the next major spec that will be written for HTML5 by W3C and WHATWG :)

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top