Date post: | 02-Jul-2015 |
Category: |
Internet |
Upload: | max-shirshin |
View: | 254 times |
Download: | 2 times |
by Max ShirshinFrontend Team Lead, Deltamethod
Consultant, Yandex
BEM it!Introduction to BEM Methodology
Why bother?
There is no unified semantic modelacross different FE technologies
● HTML stands for hypertextI've heard we mostly do web apps...
● CSS offers no structure out of the boxUsually a pile of rules put together. Sorry.
● JavaScript uses its own approaches. ...a new one comes with every framework.
● ≈ 8,500 packages in Bower registry● JavaScript:
the most popular language on GitHub Repositories created: ≈ 264,000 in 2013 ≈ 296,000 in 2012
Frameworks are not enough
BEM to the rescue
What is BEM?
BEM claims that simple semantic model (Blocks, Elements, and Modifiers)is enough to define the way you author HTML / CSS / JavaScript, structure codeand components, set up interactionand scale your project to buildan industry-leading service.
What is BEM?● BEM is a methodology, not a framework
Semantic model + best practicesfor all things frontend
● BEM is a fix for web app semantics...the same as jQuery is a fix for DOM APIs
● Originally introduced by Yandex— 19 million daily audience— 200+ web services— tools, code, tutorials, conferences— open source
Some theory
What is BEM?
BLOCK– Standalone part of an interface:
● button● text field● flyout● heading● menu
What is BEM?
BLOCK– Standalone part of an interface:
● button● text field● flyout● heading● menu
– Re-usable in different contexts– Self-sufficient
What is BEM?
ELEMENT– An integral part of a block:
● button● text field● flyout● heading● menu
What is BEM?
ELEMENT– An integral part of a block:
● button — contains no elements ● text field label● flyout title● heading logo● menu item
What is BEM?
ELEMENT– An integral part of a block:
● button — contains no elements ● text field label● flyout title● heading logo● menu item
– No standalone meaning outside of a block– Some blocks have no elements
What is BEM?
MODIFIER– Defines property or state on a block or element:
● button● text field● flyout● heading● menu item
What is BEM?
MODIFIER– Defines property or state on a block or element:
● button theme● text field editable state● flyout alignment● heading level● menu item bullet type
What is BEM?
MODIFIER– Defines property or state on a block or element:
● button theme● text field editable state● flyout alignment● heading level● menu item bullet type
– Multiple modifiers may co-existon a single block/element
BEM forms a semantic overlay over the existing DOM structure.
This overlay is called a BEM tree.
DOM tree BEM tree→
How does BEM map to DOM?● Blocks/elems/mods are denoted
with CSS classes using a naming convention.● DOM nodes can be shared:
— block1 + block2 may occupy the same container;— element1 + block2 may co-exist onthe same node.
● DOM is encapsulated:— complex DOM structure may constitutea single element
BEM HOWTOfor your beloved projectwith benefits explained
HOWTO: HTML / CSS
CSS naming conventions
“BEM uses CSS class names to denote blocks, elements and modifiers.”
CSS naming conventions
BLOCK
.b-button
.b-text-field
.b-flyout
.b-heading
.b-menu
CSS naming conventions
<ul class=”b-menu”>
<li> <a href=”/more”>Read More</a> </li>
<li> <a href=”/buy”>Buy Online</a> </li>
<li> <a href=”/buy”>Contact</a> </li>
</ul>
CSS naming conventions
ELEMENT
.b-button__icon
.b-text-field__label
.b-flyout__title
.b-heading__logo
.b-menu__item
CSS naming conventions
<ul class=”b-menu”>
<li class=”b-menu__item”> <a href=”/more”>Read More</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Buy Online</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Contact</a> </li>
</ul>
CSS naming conventions
MODIFIER
.b-button_theme_dark
.b-text-field_editable
.b-flyout_align_top
.b-heading_level_alpha
.b-menu__item_promo
CSS naming conventions
<ul class=”b-menu”>
<li class=”b-menu__item”> <a href=”/more”>Read More</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Buy Online</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Contact</a> </li>
</ul>
CSS naming conventions
<ul class=”b-menu”>
<li class=”b-menu__item b-menu__item_promo”> <a href=”/more”>Read More</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Buy Online</a> </li>
<li class=”b-menu__item”> <a href=”/buy”>Contact</a> </li>
</ul>
so structure
much semantics
wow
much semantics
very codesuch frontend
BEM CSS: best practices
1. Map the whole document to BEM blocks
2. No CSS outside of blocks
3. Independent blocks → no CSS resets
Benefits!
Drop tag names and IDs● Faster selectors● Re-use same semantics on any tag:
— <DIV class=”b-block”>
— <SPAN class=”b-block”>
— <TABLE class=”b-block”>
Benefits!
CSS specificity magic solvedPriority of CSS rules:by specificity first, then by rule ordertd.data { background-color: gray }
td.summary { background-color: white }
.total-summary { background-color: yellow }
<TD class="summary total-summary">
<!-- Still gray, baby :-( -->
</TD>
Benefits!
CSS specificity magic solvedPriority of CSS rules:by specificity first, then by rule ordertd.data { background-color: gray }
td.summary { background-color: white }
td.total-summary { background-color: yellow }
<TD class="summary total-summary">
<!-- This works, I'm yellow now -->
</TD>
Benefits!
Bye-bye CSS cascade?!
Only one CSS class needed to:● style a block container● style any element within a block● add extras/overrides with a modifier
Doesn't it cover 90% of your styling needs?
Benefits!
Bye-bye CSS cascade?!...well, not exactly.
Example of an element affected by a block modifier:
/* theme menu items for a dark theme */.b-menu_theme_dark .b-menu__item{ color: white; background-color: darkgray;}
HOWTO:Block dependencies
LoginLoginpassword
Main
username
Download Help Contact
LoginLoginpassword
Main
username
Download Help Contact
headerheader
text inputtext input text inputtext input buttonbutton
menumenu
LoginLoginpassword
Main
username
Download Help Contact
_size_small _size_small _primary
LoginLoginpassword
Main
username
Download Help Contact
.b-header .b-input { font-size: 0.85em }
.b-header .b-button { background: navy }
LoginLoginpassword
Main
username
Download Help Contact
.b-header .b-input { font-size: 0.85em }
.b-header .b-button { background: navy } !
HOWTO: JavaScript
JavaScript
Components → BlocksWork with BEM tree, not DOM tree
JavaScript
jQuery BEM helpers
https://github.com/ingdir/jquery-bemhelpers
● Helper methods to work with BEM modifiers● Callbacks on modifiers set/change
JavaScript
jQuery BEM helpers
// find a block with jQuery selectorsvar $block = component.find('div');// assign a callback to a modifier change$block.onSetMod('b-block', { status: { loaded: myCallback } });/* ... */$block.setMod('b-block', 'status', 'loaded');// 1. adds a CSS class b-block_status_loaded// 2. runs myCallback()
JavaScript
jQuery BEM plugin
http://xslc.org/jquery-bem/● Extends jQuery Sizzle with selectors for BEM
entities (mix them with “normal” selectors)● Add callbacks on modifiers set/change● Supports methods tied to blocks/elements
JavaScript
i-bem.js framework by Yandex + tutorial
https://github.com/toivonen/bem-js-tutorial
● First English draft docs (expect more!)● 100% BEM-based declarative API● Part of a larger bem-core library
HTML is no longer semantic.
JavaScript is.
HOWTO: Design / UX
BEM is the universal languagefor developers and designers,the bridge across technology gaps.
Build your block library.
The code itself is the styleguide.
UX + Frontend
● Live style guide● Always up-to-date● Prototyping mapped to code from day one● Designers and devs speak the same
language● Good for making early estimates
HOWTO: File structure
File and folder structure
Flat block structure with a folder for each block.
Simple structure for BEM beginners:
/b-block block.css block.js block.tpl ...whatever you need
File and folder structure
Advanced structure to expose semantics
/block /__elem1 block__elem1.css block__elem1.tpl /_mod block_mod.cssblock.cssblock.jsblock.tpl
Redefinition Levels/common
/block /__elem1 block__elem1.css block__elem1.tpl /_mod block_mod.cssblock.cssblock.jsblock.tpl
/my-page
/block /__elem1 block__elem1.css /_mod2 block_mod2.css
Redefinition Levels/common
/block /__elem1 block__elem1.css block__elem1.tpl /_mod block_mod.cssblock.cssblock.jsblock.tpl
/my-page
/block /__elem1 block__elem1.css /_mod2 block_mod2.css+
Build process and deployment
Use a build tool!
Borschik:an open-source build tool by Yandex
Code:https://github.com/bem/borschik
English docs:http://bem.info/articles/borschik