the thinking behind bem

56

Upload: varvara-stepanova

Post on 15-May-2015

556 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: The Thinking behind BEM
Page 2: The Thinking behind BEM

({name: "Varvara Stepanova",email: "[email protected]",twitter: "@toivonens"

});

2

Page 3: The Thinking behind BEM

3

Search

Images Video Realty Social

Blogs Apps Jobs

Maps Mail Marketplace etc.

• Russia• Turkey• Ukraine• Belarus• Kazakhstan• Azerbaijan

• 2000 devs• 150+ frontenders• 100+ services

Page 4: The Thinking behind BEM

UI Framework Team Leader

The thinking behind BEM

Varvara Stepanova

#b_ #askbem @bem_en

Page 5: The Thinking behind BEM

Block • Element • Modifier

5

Page 6: The Thinking behind BEM

Page of independent blocks

6

Page 7: The Thinking behind BEM

Page of independent blocks

7

page.html

<body class="page">

<div class="header"> <img class="logo" ... /> <div class="search">...</div> <div class="menu">...</div> </div>

<div class="layout"> <div class="sidebar">...</div> <div class="menu">...</div> </div>

</body>

Page 8: The Thinking behind BEM

Block with elements

8

Page 9: The Thinking behind BEM

page.html

Block with elements

9

<div class="tabbed-pane"> <ul> <li class="tabbed-pane__tab">Tab1</li> <li class="tabbed-pane__tab">Tab2</li> </ul> <div class="tabbed-pane__panel"> ... </div></div>

Page 10: The Thinking behind BEM

Modifiers change blocks and elements

10

<div class=" tabbed-pane tabbed-pane_theme_blue"> ...</div>

<div class=" tabbed-pane tabbed-pane_to_bottom"> ...</div>

Page 12: The Thinking behind BEM

1. Development semantics

2. Doing magic

3. Design philosophy

Thinking of...

Page 13: The Thinking behind BEM

Development semantics

Page 14: The Thinking behind BEM

Block, element, modifier

14

Page 15: The Thinking behind BEM

15

pseudoCSS

.t-pane {

width: 200px;

&_theme { &_blue { background: #9cf; } } &__tab { display: inline-block; }

CSS

.t-pane { width: 200px;}

.t-pane_theme_blue { background: #9cf;}

.t-pane__tab { display: inline-block;}

Page 16: The Thinking behind BEM

Take a block, take its element, do this!

16

JavaScript

$block('tabbed-pane') .elem('tab') .click(...);

$block('tabbed-pane') .setMod('view', 'flipped');

$block('tabbed-pane') .elem('tab') .setMod('current');

Page 17: The Thinking behind BEM

Multiple technologies

17

tabbed-pane/ tabbed-pane.css tabbed-pane.js tabbed-pane.bemhtml tabbed-pane.md

logo/ logo.png logo.css logo.bemhtml logo.md

search/ search__autocomplete.css search__autocomplete.js search__autocomplete.md search.css search.js search.bemhtml search.md

Page 18: The Thinking behind BEM

Blocks are consistent components

18

...<div class="tabbed-pane"> ... </div>...

• internal structure• associated view• corresponding behavior

Page 19: The Thinking behind BEM

Doing magic

Page 20: The Thinking behind BEM

Robots and people

Doing magic

Who serves whom?!

Page 21: The Thinking behind BEM

Заголовок (не длинней одной строки)

Do we like what robots like?

Page 22: The Thinking behind BEM

Tidy CSS code

22

:link:hover,:visited:hover{color:#f00!important}:link{color:#1a3dc1}wbr{display:inline-block}body{font:.8em Arial,Helvetica,sans-serif;position:relative;z-index:0;margin:0;padding:0 0 1em 0;color:#000;background:#fff}*{font-size:100%;margin:0}h1,h2,h3,h4,h5,h6{font-weight:normal;padding:0}table{border-collapse:collapse}th,td{padding:0;text-align:left;vertical-align:top;border-collapse:collapse}ol,ul{list-style:none}ol,ul,li{padding:0}code,input,textarea{font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}:link,:visited{text-decoration:underline}a img,fieldset{border:0}b{font-weight:normal}i{font-style:normal}.head{font-size:100%;width:100%;border-collapse:collapse}.head-g,.head-gl,.head-l,.head-gc,.head-c,.head-gr,.head-r{padding:0;vertical-align:top}.head-g{width:2%}.head-gap{display:block;visibility:hidden;width:20px}.head-gl .head-gap{width:3.1em}.head-l{width:12%;padding-top:1em;text-align:center}.head-gl{width:4%}.head-c{width:60%}.head-gr{width:4%}:link{color:#1a3dc1}:link:hover,:visited:hover{color:#f00}.head_logo{margin:au

• YUI Compressor• clean-css• Microsoft• SASS• CSS Tidy• Slimmer• Stilys• whatever

Page 23: The Thinking behind BEM

CSS best practices

23

/* Use shorthand */#super-box { margin-top: 9px; margin-right: 8px; margin-bottom: 0; margin-left: 5px; margin: 9px 8px 0 5px;}

/* Numeric font-weight */p.about { font-weight: bold; font-weight: 700;}

/* Shorter color code */li.menu { color: yellow; color: #FF0; background-color: #F00; background-color: red;}

/* Combine selectors */h1, h2, h3 { text-decoration: none;}

Page 24: The Thinking behind BEM

bem.info/tools/csso

24

BEFORE.test1 { border: none; background-color: red; margin-top: 2em; margin-left: 4px; margin-bottom:3px; margin-right: 0.1em; font-weight: bold;}

.test2 { border: none;}

.test3 { margin-top: 2em; margin-bottom: 2em; margin-right: 2em; margin-left: 2em; background-color: #FF0000; font-weight: normal;}

AFTER.test1 { background-color: red; margin: 2em .1em 3px 4px; font-weight: 700}

.test1, .test2 { border: none}

.test3 { margin: 2em; background-color: red; font-weight: 400}

Page 25: The Thinking behind BEM

Modular or solid?

25

Page 26: The Thinking behind BEM

26

human@import url(blocks/header.css);@import url(blocks/layout.css);@import url(blocks/menu.css);@import url(blocks/search.css);@import url(blocks/button.css);@import url(blocks/text.css);@import url(blocks/footer.css);

browser.header { background: #000; color: #fff; font-size: 1.5em;}.layout { ... }.menu { ... }.search__input { width: 100%; margin: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;}.search_button { margin: 0;}

blocks/ button.css footer.css header.css layout.css menu.css search.css

Page 27: The Thinking behind BEM

CSS flattening with Borschik

27

index.css

@import url(blocks/header/header.css);@import url(blocks/menu/menu.css);...

_index.css

.header { ...}.menu { ...}

Page 28: The Thinking behind BEM

CSS flattening with Borschik

28

blocks/my-block/my-block.css

.my-block { background: url(bg.png);}

pages/_index.css

/* Included blocks/my-block/my-block.css */.my-block background: url(../blocks/my-block/bg.png);}...

Page 29: The Thinking behind BEM

JavaScript flattening with Borschik

29

index.js

/*borschik:include:blocks/menu/menu.js*//*borschik:include:blocks/tabbed-pane/tabbed-pane.js*/...

_index.js

/* Included blocks/menu/menu.js */(function($) { $block('menu').elem('item').on('click', function() { $(this).toggleMod('state', 'current'); });})(jQuery);

Page 30: The Thinking behind BEM

Borschik freezes images

30

blocks/my-block/my-block.css

.my-block { background: url(bg.png);}

pages/_index.css

/* Included blocks/my-block/my-block.css */.my-block { background: url(_freeze/jUK5O9GsS2gPWOhRMeBxR0GThf0.png);}...

Page 31: The Thinking behind BEM

bit.ly/about-borschikBorschik. Simply powerful :-)

31

Page 32: The Thinking behind BEM

Code interfaces, not languages

32

HTML<!DOCTYPE html><html> <head> <title>Awesome online bookshop</title> <link rel="stylesheet" href="style.css"/> <script src="magic.js"></script> </head> <body> <div class="head"> <ul class="menu"> <li class="menu__item"><a href="/">Home</a></li> <li class="menu__item"><a href="/news">News</a></li> ... </ul> <div class="phone">+3 71 1234567</div> </div> <div class="layout"> ...

general CSS.head { ... }.menu { ... }.menu__item { ... }.phone { ... }.layout { ... }...

CSS for IE.menu { ... }.menu__item { ... }.button { ... }...

JavaScript(function($) { $block('menu').elem('item').on('click', function() { $(this).toggleMod('state', 'current'); });})(jQuery);...

Page 33: The Thinking behind BEM

Code interfaces, not languages

33

BEM tree

{ block: 'page', content: [ { block: 'head', content: [ { block: 'logo' }, { block: 'search', ... }, { block: 'menu' } ] }

Page 34: The Thinking behind BEM

Supply a browser with magic outcome

34

page.html

<!DOCTYPE html><html class="i-ua_js_no i-ua_css_standart"><head><meta charset=UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, IE=edge"><script type="text/javascript">//<!--;(function(d,e,c,r){e=d.documentElement;c="className";r="replace";e[c]=e[c][r]("i-ua_js_no","i-ua_js_yes");if(d.compatMode!="CSS1Compat")e[c]=e[c][r]("i-ua_css_standart","i-ua_css_quirks")}(document));//--></script><!--[if gt IE 9]><!--><link rel="stylesheet"

page.css

:link:hover,:visited:hover{color:#f00!important}:link{color:#1a3dc1}wbr{display:inline-block}body{font:.8em Arial,Helvetica,sans-serif;position:relative;z-index:0;margin:0;padding:0 0 1em 0;color:#000;background:#fff}*{font-size:100%;margin:0}h1,h2,h3,h4,h5,h6{font-weight:normal;padding:0}table{border-collapse:collapse}th,td{padding:0;text-align:left;vertical-align:top;border-collapse:collapse}ol,ul{list-style:none}ol,ul,li{padding:0}code,input,textarea{font-family:Arial,Helvetica,sans-serif}a{text-decoration:none}:link,:visited{text-decoration:underline}a

page.js

jQuery.cookie=function(b,j,m){if(typeof j!="undefined"){m=m||{};if(j===null){j="";m.expires=-1}var e="";if(m.expires&&(typeof m.expires=="number"||m.expires.toUTCString)){var f;if(typeof m.expires=="number"){f=new Date();f.setTime(f.getTime()+(m.expires*24*60*60*1000))}else{f=m.expires}e="; expires="+f.toUTCString()}var l=m.path?"; path="+(m.path):"";var g=m.domain?"; domain="+(m.domain):"";var a=m.secure?"; secure":"";document.cookie=[b,"=",encodeURIComponent(j),e,l,g,a].join("")}else{var d=null;if(document.cookie&&document.cookie!=""){var k=document.cookie.split(";");for(var h=0;h<k.length;h++){var

Page 35: The Thinking behind BEM

Introducing magic into development

35

developer browserbuildingprocess

Page 36: The Thinking behind BEM

Building process

Production

• rebuild the whole project

Development

• live edit• partial rebuild• tracking changes

36

› bem make › bem server

Page 38: The Thinking behind BEM

Design philosophy

Page 39: The Thinking behind BEM

39

Page 40: The Thinking behind BEM

40

Page 41: The Thinking behind BEM

bit.ly/bem-riga-2012 What you can borrow from Yandex front-end dev

Independent CSS blocks

41

• blocks– are not affected by parents– do not affect children

• developer– names blocks with CSS classes– keeps off tag selectors– avoids cascade

Page 42: The Thinking behind BEM

Imperative vs declarative programming

42

COULD YOU PLEASE

?

Page 43: The Thinking behind BEM

Declarations in CSS

43

file1.css

.button { background-color: red; font-size: 1.5em;}

file2.css

.button { background-color: green; margin: .2em;}

Page 44: The Thinking behind BEM

Declarative JavaScript

44

file1.js

BEM.DOM.decl('button', {

/* Basic block implementation */

});

file2.js

BEM.DOM.decl('button', {

/* Extending block implementation */

});

Page 45: The Thinking behind BEM

Declarative JavaScript

45

BEM.DOM.decl('button', {

onSetMode: {

'active' : {

'yes' : function() { /* Do smth when active */ },

'no' : function() { /* Do smth else when not */ }

}

}

}); <input class="button button_active_yes" ... /><input class="button button_active_no" ... />

Page 46: The Thinking behind BEM

Combinatorics

46

Page 47: The Thinking behind BEM

simple & simple=

complex

47

Page 48: The Thinking behind BEM

Extended by a modifier

48

button.css

.button { background-color: red; font-size: 1.5em;}

button_size_large.css

.button_size_large { font-size: 3em;}

<input class="button button_size_large" ... />

Page 49: The Thinking behind BEM

Extended by a modifier

49

button.js

BEM.DOM.decl('button', { /* Basic implementation for all the buttons */});

button_size_large.js

BEM.DOM.decl({ block: 'button', mod: 'size', val: 'large'}, { /* Additional implementation for large sized buttons */});

<input class="button button_size_large" ... />

Page 50: The Thinking behind BEM

Extended by a block level

50

library-blocks/

button/ button.css button.js

menu/ search/ tabbed-pane/

blocks/ button/ button.css

library-blocks/button/button.css

.button {

background-color: red; font-size: 1.5em;

}

blocks/button/button.css

.button {

background-color: green; padding: .2em;

}

Page 51: The Thinking behind BEM

Extended by a block level

51

library-blocks/

button/ button.css button.js

menu/ search/ tabbed-pane/

blocks/ button/ button.js

library-blocks/button/button.js

BEM.DOM.decl('button', {

/* Basic implementation for all the buttons*/

});

blocks/button/button.js

BEM.DOM.decl('button', {

/* Additional implementation for the buttons of the project */

});

Page 52: The Thinking behind BEM

Large profit of small things

• larger entities made up from smaller ones– code re-use– consistency

• everything is a block

52

Page 53: The Thinking behind BEM

Revelations

• Development semantics• Magic building tricks• Declarativeness• Combinatory methods• Block levels and libraries

53

Page 54: The Thinking behind BEM

code more to code less

54

Page 55: The Thinking behind BEM

[email protected]

Varvara StepanovaUI Framework Team Lead

@toivonens

Thank you

Page 56: The Thinking behind BEM

#b_ #askbem

@bem_en

56

?