• BEM logo. Source: P. Silva 2016.
    BEM logo. Source: P. Silva 2016.
  • An overview of BEM. Source: Adapted from BEM 2019b.
    An overview of BEM. Source: Adapted from BEM 2019b.
  • Problems solved by BEM. Source: Tadatuta 2019.
    Problems solved by BEM. Source: Tadatuta 2019.

BEM Methodology

Avatar of user mohanjo
mohanjo
947 DevCoins
Avatar of user arvindpdmn
arvindpdmn
2 DevCoins
2 authors have contributed to this article
Last updated by arvindpdmn
on 2019-02-08 12:41:43
Created by mohanjo
on 2019-02-06 06:16:05
Improve this article. Show messages

Summary

BEM logo. Source: P. Silva 2016.
BEM logo. Source: P. Silva 2016.

When updating web/mobile user interfaces, frontend developers often worry about breaking existing code or introducing inconsistencies. Selecting elements on a UI is often problematic because of long cascading rules, nested styles, rules that are unnecessarily high in specificity, and naming everything in the global namespace. BEM provides a modular approach to solve these problems.

BEM is a methodology, an approach and a naming convention to write better CSS styling and achieve consistent JS behaviour. BEM stands for Block, Element and Modifier. These three are called BEM Entities.

BEM is not a W3C standard but it's recommended by those who have adopted it and reaped its benefits. Among its adopters are Yandex, Google, BBC, Alfa Bank, and BuzzFeed. BEM also works nicely with CSS languages (Sass, etc.), and frontend frameworks (React, etc.).

Milestones

Dec
1996

The first version of Cascading Style Sheets (CSS) comes out as a W3C Recommendation. The idea of having style sheets can be traced to Tim Berners-Lee, who used it in his NeXT browser (1990), and Pei Wei's Viola browser (1992). Håkon Wium Lie released an initial draft in October 1994.

2006

At Yandex, developers find that for large projects, layouts are becoming difficult to maintain. Long cascading rules and dependencies cause changes in one web page to affect many others. To solve this, they introduce the concept of blocks. A block is part of a page or layout defined semantically or visually. A block is given a unique CSS class name. Nodes within blocks are called elements. For example, logo is an element with a header block.

2007

Block names use prefixes to emulate namespaces. Each prefix has its own semantics: b- for blocks, h- for block wrappers, l- for layouts, g- for global styles. This is also when modifiers are introduced to indicate block state or property. Modification can be context-dependent such as location; or context-independent.

Mar
2008

With the release of Lego 2.0, the unified styling framework at Yandex, BEM is formally born. Blocks are primary units. A block can be used anywhere on the page. Each block is stored in a separate folder with its own documentation. Blocks used are noted in XML files and used to generate CSS files.

2009

Folks at Yandex invent Absolutely Independent Blocks (AIB) to solve the problem of slow DOM updates. Each DOM node has its own class. Tag rules are avoided in CSS.

2010

BEM is open sourced along with some essential BEM tools.

2015

CSS Modules is born with the initial commit happening in May 2015. BEM requires developers to choose unique class names and does not provide encapsulation. CSS Modules solves this by dynamically creating class names and localising styles. Thus, tooling is just as important as conventions. CSS Modules doesn't replace BEM. It makes it easier to implement BEM.

Discussion

  • Could you explain BEM with an example?
    An overview of BEM. Source: Adapted from BEM 2019b.
    An overview of BEM. Source: Adapted from BEM 2019b.

    BEM is a component-based approach to design a user interface for the web/mobile. For example, we can identify components such as header, menu, logo, search and login on a typical web page. In BEM, we call these components blocks, each having a well-defined purpose or semantics. It's also apparent that a block can contain other blocks within it. However, each block is also independent of other blocks and can be reused elsewhere. For example, it's not necessary that the login block must be part of the header block. It could be moved to a sidebar in a redesigned page layout.

    Blocks can also contain elements that cannot exist outside their parent blocks. For example, a menu block is composed of menu items, each of which is an element in BEM terminology.

    Finally, an element within a block can be selectively modified depending on the context. For example, in a menu block, the active menu item could be styled differently. This modification is done using modifiers. Modifiers are optional.

  • What are the advantages of adopting the BEM methodology?
    Problems solved by BEM. Source: Tadatuta 2019.
    Problems solved by BEM. Source: Tadatuta 2019.

    BEM enables flexible maintainable code. Components can be reused. Code becomes more consistent since the rules are clear. It's easier to scale to large projects. Teamwork is easier because everyone is familiar with BEM conventions. Since the approach is based on independent blocks, work can be clearly partitioned, with each team member working on a different block.

    More specifically, every BEM CSS class is unique and self-sufficient. BEM doesn't need nesting of styles. We don't need long and inefficient selectors to match specific elements. BEM avoids name collisions due to its consistent naming convention. The naming convention also makes the CSS self-documenting: the relationships among DOM nodes is easier to see. DOM nodes are selected more efficiently with managed specificity.

  • What's the default naming conventions followed in BEM?

    Let's consider the following: block-name__elem-name_mod-name_mod-val. We note that names are all in lowercase, underscores are used as separators between BEM entities, and hyphens are used within names for better readability. We use double underscore to separate block from element; single underscore to separate block/element name from its modifier; single underscore to separate modifier name and modifier value.

    Consider these examples:

    • main-menu_hidden: main-menu is the block, hidden is the modifier.
    • menu_theme_islands: menu is the block, theme is the modifier, islands is the theme being specified (modifier value).
    • menu__item_type_radio: menu is the block, item is its element, type is item's modifier, radio is the modifier's value.
    • main-menu__item_black-listed: main-menu is the block, item is its element, black-listed is item's modifier.
  • What other naming conventions are common in the BEM community?
    Kevin Powell explains the Two Dashes convention. Source: Powell 2018.

    While there's a default naming convention in BEM, you can create your own convention. Most importantly, the convention should clearly separate blocks, elements and modifiers. Other than the default one, the following conventions are used in the BEM community:

    • Two Dashes: block-name__elem-name--mod-name--mod-val: this naming is popular, probably because it tolerates legacy names that have underscores in them since double hyphens are used between an elements, modifiers and values.
    • CamelCase: blockName-elemName_modName_modVal
    • React: BlockName-ElemName_modName_modVal
    • No Namespace: _modname: no reference to block or element and hence of limited usefulness.
  • What technologies assist in implementing BEM?

    A block is not just about CSS. It encapsulates behaviour (JavaScript), templates, styles (CSS), documentation, and other implementation technologies. Developers can adopt any implementation technology of their choice. As a sample, we note the following:

    • Styling: CSS, Stylus, Sass
    • Behaviour: JavaScript, CoffeeScript
    • Templates: BEMHTML, BH, Pug, Handlebars, XSL
    • Documentation: Markdown, Wiki, XML
  • Could you share some BEM best practices?

    An important principle of BEM is to avoid selectors based on ID or tag name. Only class names are used, and these can be reused easily regardless of the tag. It's also allowed to use multiple BEM entities on the same DOM node.

    We can use nesting in BEM but it's not recommended. Nesting increasing code coupling and inhibits reuse. Likewise, combined selectors (eg. .btn.btn_error) are not recommended.

    Use only a single double underscore in a name: c-card__img rather than c-card__body__img. Use namespaces to improve readability: c- for component, l- for layout, h- for helpers, is- or has- for states , js- for JavaScript hooks.

    External geometry and positioning (such as padding) should be done on parent node so that the current block can be reused elsewhere. Use mixes to apply the same style to multiple DOM nodes. This approach is better than using group selectors.

    Take an object-oriented approach to design. Design in terms of reusable blocks. Use principles such as single responsibility principle and open/closed principle. Don't repeat yourself (DRY). Prefer composition over inheritance. Organize your files into a clear folder structure.

  • What are some criticisms of BEM?

    Since BEM avoids the use of IDs or tag names, class names have to be unique. Giving these names can be a difficult task. Long class names bloat markup. To reuse UI components, we need to explicitly extend them.

    As an example, a modifier will need its own class name but giving names for each DOM node that needs to be styled with this modifier can be cumbersome. An alternative is to use utility classes, named with u- prefix. The trade-off is that this will result in nested CSS. Thus, a DOM node is selected as menu__item u-active rather than menu__item-active.

    Since DOM nodes are marked with BEM entities, BEM creates a semantic overlay on the DOM. This is called BEM Tree. While some regard this as a useful thing, others claim that BEM unnecessarily makes the markup semantic.

Sample Code

  • /* Source: https://css-tricks.com/forums/topic/less-bem/
       Accessed: 2019-02-08
    */
     
    /* Less */
    block {
      &__element {
        &--modifier-one {
           color: red;
        }
        &--modifier--two {
           color: blue;
        }
      }
    }
     
    /* CSS compiled from the above Less code */
    block__element--modifier-one {
      color: red;
    }
    block__element--modifier-two {
      color: blue;
    }

References

  1. BEM. 2019a. "The history of BEM." BEM. Accessed 2019-02-06.
  2. BEM. 2019b. "Key concepts." BEM. Accessed 2019-02-06.
  3. BEM. 2019c. "Naming convention." BEM. Accessed 2019-02-06.
  4. BEM. 2019d. "CSS with BEM." BEM. Accessed 2019-02-06.
  5. Berner, David. 2016. "Battling BEM CSS: 10 Common Problems And How To Avoid Them." Smashing Magazine, June 01. Accessed 2019-02-06.
  6. Bos, Bert. 2016. "A brief history of CSS until 2016." W3C, December 17. Accessed 2019-02-06.
  7. Dutartre, Thibaut. 2016. "Toward CSS modules." Putain de code!, February 23. Accessed 2019-02-06.
  8. Levine, Garrett. 2016. "React Components & B.E.M." Medium, October 02. Accessed 2019-02-06.
  9. Matijević, Tomislav. 2016. "Introduction To BEM Methodology." Engineering Blog, Toptal, April. Accessed 2019-02-06.
  10. P. Silva, Pablo Henrique. 2016. "BEM — Blocks, Elements and Modifiers." tldr tech, on Medium, April 12. Accessed 2019-02-06.
  11. Perezpriego. 2017. "CSS Evolution: From CSS, SASS, BEM, CSS Modules to Styled Components." Medium, January 03. Accessed 2019-02-06.
  12. Powell, Kevin. 2018. "Why I use the BEM naming convention for my CSS." YouTube, November 09. Accessed 2019-02-06.
  13. Rendle, Robin. 2015. "BEM 101." CSS-Tricks, April 02. Updated 2016-03-09. Accessed 2019-02-06.
  14. Roberts, Harry. 2016. "Nesting Your BEM?" CSS Wizardry, November 28. Accessed 2019-02-06.
  15. Shirshin, Maxim. 2014. "Scaling Down The BEM Methodology For Small Projects." Smashing Magazine, July 17. Accessed 2019-02-06.
  16. Tadatuta. 2019. "BEM Methodology." Tadatuta. Accessed 2019-02-06.
  17. css-modules GitHub. 2017. "css-modules/css-modules." October 28. Accessed 2019-02-06.

Milestones

Dec
1996

The first version of Cascading Style Sheets (CSS) comes out as a W3C Recommendation. The idea of having style sheets can be traced to Tim Berners-Lee, who used it in his NeXT browser (1990), and Pei Wei's Viola browser (1992). Håkon Wium Lie released an initial draft in October 1994.

2006

At Yandex, developers find that for large projects, layouts are becoming difficult to maintain. Long cascading rules and dependencies cause changes in one web page to affect many others. To solve this, they introduce the concept of blocks. A block is part of a page or layout defined semantically or visually. A block is given a unique CSS class name. Nodes within blocks are called elements. For example, logo is an element with a header block.

2007

Block names use prefixes to emulate namespaces. Each prefix has its own semantics: b- for blocks, h- for block wrappers, l- for layouts, g- for global styles. This is also when modifiers are introduced to indicate block state or property. Modification can be context-dependent such as location; or context-independent.

Mar
2008

With the release of Lego 2.0, the unified styling framework at Yandex, BEM is formally born. Blocks are primary units. A block can be used anywhere on the page. Each block is stored in a separate folder with its own documentation. Blocks used are noted in XML files and used to generate CSS files.

2009

Folks at Yandex invent Absolutely Independent Blocks (AIB) to solve the problem of slow DOM updates. Each DOM node has its own class. Tag rules are avoided in CSS.

2010

BEM is open sourced along with some essential BEM tools.

2015

CSS Modules is born with the initial commit happening in May 2015. BEM requires developers to choose unique class names and does not provide encapsulation. CSS Modules solves this by dynamically creating class names and localising styles. Thus, tooling is just as important as conventions. CSS Modules doesn't replace BEM. It makes it easier to implement BEM.

Tags

See Also

  • Modular CSS Frameworks
  • Cascading Style Sheets
  • Less (Stylesheet Language)
  • Sass (Stylesheet Language)
  • Naming Conventions
  • Coding Guidelines

Further Reading

  1. Popa, Andrei. 2016. "BEM I (finally) understand." AlphaSights, on Medium, May 31. Accessed 2019-02-06.
  2. Belaya, Inna. 2018. "BEM For Beginners: Why You Need BEM." Smashing Magazine, June 18. Accessed 2019-02-06.
  3. Hubert, Victor. 2017. "A practical introduction to the BEM CSS methodology." Medium, January 19. Accessed 2019-02-06.
  4. Perezpriego. 2017. "CSS Evolution: From CSS, SASS, BEM, CSS Modules to Styled Components." Medium, January 03. Accessed 2019-02-06.
  5. Shirshin, Maxim. 2014. "Scaling Down The BEM Methodology For Small Projects." Smashing Magazine, July 17. Accessed 2019-02-06.
  6. Berner, David. 2016. "Battling BEM CSS: 10 Common Problems And How To Avoid Them." Smashing Magazine, June 01. Accessed 2019-02-06.

Article Stats

Author-wise Stats for Article Edits

Author
No. of Edits
No. of Chats
DevCoins
2
0
947
1
0
2
1415
Words
0
Chats
3
Edits
2
Likes
999
Hits

Cite As

Devopedia. 2019. "BEM Methodology." Version 3, February 8. Accessed 2019-12-12. https://devopedia.org/bem-methodology