BEM
let's write bem correctly
BEM
Block Element Modifer - is a methodology that helps you to achieve reusable components and enables code sharing in the frontend
Created by Yandex in 2005
Code that is hard to maintain
// How those classes are related?
<div class="media user premium">
<img class="img photo avatar" src="" />
<p class="body info">...</p>
</div>
... and code that is easy to maintain
// It's BEM baby
<div class="media user user--premium">
<img class="media__img user__photo avatar" src="" />
<p class="media__body user__info">...</p>
</div>
BEM BLock
Text
Text
Text
BEM Block
BEM Element
BEM Modifier
Yandex naming convention
<div class="block-name__elem-name_mod-name_mod-val">
Yandex naming convention
<div class="block-name">
// block name
HTML
<div class="menu">...</div>
CSS
.menu { color: red; }
Yandex naming convention
<div class="block-name__elem-name">
// element name
HTML
<div class="menu">
...
<span class="menu__item"></span>
</div>
CSS
.menu__item { color: red; }
Yandex naming convention
<div class="block-name__elem-name_mod-name_mod-val">
// boolean modifier & key-value type modifier
HTML
<div class="menu menu_hidden">...</div>
<div class="menu menu_theme_xmas">...</div>
CSS
.menu_hidden { display: none }
.menu_theme_xmas { color: green; }
Harry Roberts' style
<div class="block-name__element-name--state_active">
CamelCase style
<div class="blockName__elementName--state_active">
'Sans underscore' style
<div class="blockName-elementName--modName--modVal">
You can use prefixes
- b- common blocks
- l- layout grids
- h- holsters
- js- js blocks
- qa- for tests
- etc.
Bem example
Dom-Tree
BEM-Tree
// html
<ul>
<li>
<a>
<span></span>
</a>
</li>
</ul>
// css
.ul {}
.ul > li {}
.ul > li > a {}
.ul > li > a > span {}
// html
<ul class="menu">
<li class="menu__item">
<a class="menu__link">
<span class="menu__text"></span>
</a>
</li>
</ul>
// css
.menu {}
.menu__item {}
.menu__link {}
.menu__text {}
BEM: The Good Parts
.signup__account__user-name__input { ... }
?
WRONG!
Before
After
How to fix block__elem__elem?
<div class="block">
<div class="block__elem1">
<div class="block__elem1__elem2"></div>
</div>
</div>
<div class="block1">
<div class="block1__elem1 block2">
<div class="block2__elem1"></div>
</div>
</div>
// OR
<div class="block1">
<div class="block1__elem1">
<div class="block1__elem2"></div>
</div>
</div>
Html
Css
CSS styles
<div class="block">
<div class="block__element">
</div>
</div>
.block .block__element {
...
}
Html
Css
Wrong CSS styles
<div class="block">
<div class="block__elememt">
</div>
</div>
/* bad */
.block .block__element {
...
}
/* good */
.block {
...
}
.block__element {
...
}
Why the modifier CSS classes are not represented as a combined selector?
<div class="block mod">...</div>
or
<div class="block block--mod">...</div>
Any ideas?
- Namespace
- Mixes - <div class="menu__item button active">
- Code searching - find active and button--active
Avoid Sass' @extend
<div class="menu menu--hidden">...</div>
OR
<div class="menu--hidden">...</div>
/* good */
.menu,
.menu--hidden,
.menu--other-modifier {
// base styles
}
/* better */
.menu {
// base styles
}
.menu--hidden {...}
.menu--other-modifier {...}
- CSS (clean and minimum sized)
- Descriptive
- Flexibility and consistency (same styles applied twice for two modifiers)
Can I create a global modifier applicable to any block?
visible, invisible, opacity50 and etc.
// css
.hidden { display: none }
/* ... */
.block { display: block }
// html
<div class="block hidden">
you still see me
</div>
<div class="block mod1 mod2">
you have no control over the block
</div>
Don’t be afraid of long class names
Focus on self documenting class names. Don’t be afraid of long class names! His advice – “Use long, descriptive class names over short names that don’t document themselves.”
Bem Tools
- bem-core
- bem-components
- bem-bl
- bem-mvc
- bem-history
- gemini
angular-bem
A set of directives to simplify your workflow with BEM-markup in Angular-based applications.
How to use
bower install angular-bem
or
npm install angular-bem
// include module
angular.module('app', ['tenphi.bem']);
// create a simple markup
<body ng-app="app">
<div block="my-block" mod="{ modName: 'value' }">
<div elem="my-element" mod="{ modName: 'value', secondModName: true }"></div>
</div>
</body>
// result
<div class="my-block my-block--mod-name_value">
<div class="my-block__my-element
my-block__my-element--mod-name_value
my-block__my-element--second-mod-name">
</div>
</div>
Install
Using BEM filter with Emmet
Alternatives
Q & A
Stay BEMed!
Useful links
BEM Block Element Modifier
By Sergey Bolshov
BEM Block Element Modifier
- 1,503