the thinking behind bem

Post on 15-May-2015

556 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

({name: "Varvara Stepanova",email: "toivonen@yandex-team.ru",twitter: "@toivonens"

});

2

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

UI Framework Team Leader

The thinking behind BEM

Varvara Stepanova

#b_ #askbem @bem_en

Block • Element • Modifier

5

Page of independent blocks

6

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>

Block with elements

8

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>

Modifiers change blocks and elements

10

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

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

1. Development semantics

2. Doing magic

3. Design philosophy

Thinking of...

Development semantics

Block, element, modifier

14

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;}

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');

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

Blocks are consistent components

18

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

• internal structure• associated view• corresponding behavior

Doing magic

Robots and people

Doing magic

Who serves whom?!

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

Do we like what robots like?

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

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;}

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}

Modular or solid?

25

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

CSS flattening with Borschik

27

index.css

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

_index.css

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

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);}...

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);

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);}...

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

31

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);...

Code interfaces, not languages

33

BEM tree

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

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

Introducing magic into development

35

developer browserbuildingprocess

Building process

Production

• rebuild the whole project

Development

• live edit• partial rebuild• tracking changes

36

› bem make › bem server

Design philosophy

39

40

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

Imperative vs declarative programming

42

COULD YOU PLEASE

?

Declarations in CSS

43

file1.css

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

file2.css

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

Declarative JavaScript

44

file1.js

BEM.DOM.decl('button', {

/* Basic block implementation */

});

file2.js

BEM.DOM.decl('button', {

/* Extending block implementation */

});

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" ... />

Combinatorics

46

simple & simple=

complex

47

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" ... />

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" ... />

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;

}

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 */

});

Large profit of small things

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

• everything is a block

52

Revelations

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

53

code more to code less

54

toivonen@yandex-team.ru

Varvara StepanovaUI Framework Team Lead

@toivonens

Thank you

#b_ #askbem

@bem_en

56

?

top related