239

Жека Константинов, Дима Белицкий, Слава Аристов — Мастер-класс: разрабатываем сайт с нуля на полном

  • Upload
    yandex

  • View
    955

  • Download
    1

Embed Size (px)

DESCRIPTION

БЭМ — это технология разработки сайтов, которые нужно быстро создать и долго поддерживать. Она используется в разработке фронтенда почти всех сервисов Яндекса и успела обрасти большим набором библиотек и инструментов, которым мы хотим с вами поделиться. Имея в своих руках обширный арсенал БЭМ со всей его модульностью и мощью, остаётся «всего-то» придумать идею и реализовать её. На мастер-классе вы сможете вместе с нами создать то, что мы «только что» придумали. Вы узнаете, в чём преимущество вёрстки независимыми блоками и что такое «уровни переопределения», познакомитесь с готовыми библиотеками блоков и инструментами для автоматизации сборки. Мы покажем, как разные инструменты для упрощения жизни разработчика, вроде autoprefixer, css-препроцессора roole и модульной системы YModules, встраиваются в процесс разработки на БЭМ и создают по-настоящему удобную платформу. На живом примере мы объясним, в чём польза декларативного подхода, когда одни и те же идеи можно использовать как для CSS, так и для JS. Более того, декларативным шаблонам: BEMHTML и BEMTREE, которые позволяют преобразовывать сырые данные во view-ориентированный BEMJSON, — будет посвящена одна из трёх частей мастер-класса. В результате получится работающий сайт, а вы на практике познакомитесь с полным стеком БЭМ-технологий. После мастер-класса запланировано дополнительное время на полезное общение: вы сможете рассказать о трудностях, с которыми встретились при реализации проекта на БЭМ, и мы вместе подумаем, как воплотить вашу идею в жизнь.

Citation preview

  • 1. - , , BEMup , 18 2014

2. 3 3 [email protected] @sipayrt github.com/sipayrt 3. 4 [email protected] @dabelitsky github.com/dab 4. 5 5 [email protected] @aristov7 github.com/aristov 5. ? 6 CSS 6. ? 7 CSS 7. ? 8 CSS JavaScript + BEM 8. ? 9 CSS JavaScript + BEM - 9. - 10. ?! 11 API 11. 12 12. CSS + 13. ? 14. ? 15 15. ? 16 16. ? 17 , , 17. ? 18 bem.info bit.ly/1hMHNB2 - bit.ly/1hMCKk5 18. 19. 20 #menu li! {! font-size: 16px;! } 20. 21

  • ! !!!!
  • ! !!!!
  • ! !!!!!!!!! !!!!!

21. 22

  • ! !!!!
  • ! !!!!
  • ! !!!!!!!!! !!!!!

22. 23. 24 .b-header .link! {! background: no-repeat url(b-logo.svg);! }! ! 24. 25 25. 26 .b-header .link! {! background: no-repeat url(b-logo.svg);! }! ! .b-header .b-social .link! {! color: green;! }! 26. 27 27. 28 /* */! .b-header .link! {! background: url();! }! ! .b-header .b-social .link! {! color: #fff;! }! 28. 29 /* */! .b-header .link! {! background: url();! }! ! .b-header .b-social .link! {! color: #fff;! }! /* */! .header__link! {! background: url();! }! ! .social__link! {! color: #fff;! } 29. 30 30. 31 31. 32 32. 33 33. 34 34. 35 35. 36 36. 37 .cat_theme_red! {! background: #dc9d42;! }! 37. 38 .cat_theme_red! {! background: #dc9d42;! }! ! .cat_walking! {! animation-duration: 300s;! }! ! 38. 39 .cat_theme_red! {! background: #dc9d42;! }! ! .cat_walking! {! animation-duration: 300s;! }! ! .cat__tail_direction_top! {! top: -200px;! }! 39. 40 40. 41. 42 42. 43 blocks/! ! ! button.css! !button.js! ! ! input.css! ! ! input.js! ! ! input.html! ! ! logo.css! ! ! logo.js! ! ! logo.png 43. 44 blocks/! ! header/! ! logo/! ! button/! !! __icon/! ! ! ! ! ! button__icon.bemhtml! ! ! ! ! ! button__icon.css! ! ! ! ! ! button__icon.png! _size/! ! ! button_size_s.css! !! ! button_size_m.css! !! button.css! !! button.js 44. 45 blocks/! ! header/! ! logo/! ! button/! !! __icon/! ! ! ! ! ! button__icon.bemhtml! ! ! ! ! ! button__icon.css! ! ! ! ! ! button__icon.png! _size/! ! ! button_size_s.css! !! ! button_size_m.css! !! button.css! !! button.js 45. 46 blocks/! ! header/! ! logo/! ! button/! !! __icon/! ! ! ! ! ! button__icon.bemhtml! ! ! ! ! ! button__icon.css! ! ! ! ! ! button__icon.png! _size/! ! ! button_size_s.css! !! ! button_size_m.css! !! button.css! !! button.js 46. 47 blocks/! ! header/! ! logo/! ! button/! !! __icon/! ! ! ! ! ! button__icon.bemhtml! ! ! ! ! ! button__icon.css! ! ! ! ! ! button__icon.png! _size/! ! ! button_size_s.css! !! ! button_size_m.css! !! button.css! !! button.js 47. 48 @import url(../../lego/button/button.css);! @import url(../../lego/button/__icon/button__icon.css);! @import url(../../lego/button/_size/button_size.css);! ! 48. 49 @import url(../../lego/button/button.css);! @import url(../../lego/button/_size/button_size.css);! ! 49. 50 bem.info bit.ly/1eAsQBo 50. 51 51. 52 52. 53 ! ! ! bem-components! !!!!desktop.blocks/! !!!!!!!!form/! !!!!!!!!!!!!form.css 53. 54 ! ! bem-components/! !!!!desktop.blocks/! !!!!!!!!form/! !!!!!!!!!!!!form.css! sssr/! !!!!desktop.blocks/! !!!!!!!!form/! !!!!!!!!!!!!form.css 54. 55 @import url(../../bem-components/desktop.blocks/form/form.css);! @import url(../../desktop.blocks/form/form.css);! ! 55. 56 /* ../../bem-components/desktop.blocks/form/form.css begin */! .form! {! background: #fff;! }! /* ../../bem-components/desktop.blocks/form/form.css end */! ! /* ../../desktop.blocks/form/form.css begin */! .form! {! background: ;! }! /* ../../desktop.blocks/form/form.css end */! 56. 57 57. 58 /* common.blocks */! .button! {! display: inline-block;! }! ! /* desktop.blocks */! .button! {! background-color: green;! }! ! /* touch.blocks */! .button! {! -webkit-touch-callout: none;! } 58. 59 bem.info bit.ly/1eAsQBo bit.ly/1m8ijzQ 59. 60. 61 @import url(../../common/block/global/_type/global_reset.css);! @import url(../../common/block/l-head/l-head.css);! @import url(../../common/block/header/__logo/header__logo.css);! @import url(../../common/block/header/_type/header_type_yandex.css);! @import url(../../common/block/header/__tabs/header__tabs.css);! @import url(../../common/block/b-dropdown/b-dropdown.css);! @import url(../../common/block/b-dropdown/__text/b-dropdown__text.css);! @import url(../../common/block/b-link/b-link.css);! @import url(../../common/block/dropdown/__arrow/dropdown__arrow.css);! @import url(../../common/block/header/__search/header__search.css);! @import url(../../common/block/b-search/b-search.css);! @import url(../../common/block/b-search/__input/b-search__input.css);! @import url(../../common/block/b-search/__sample/b-search__sample.css);! @import url(../../common/block/b-search/__precise/b-search__precise.css);! @import url(../../common/block/b-search/__button/b-search__button.css);! @import url(../../common/block/header/__userinfo/header__userinfo.css);! 61. 62 62. 63 63. 64 bem-tools/enb borschik CSSO + SVGO BEMHTML 64. 65 bem.info/tools bit.ly/1qL91tg 65. Lets code CSS 66. BEMHTML + BEMTREE 67. 68. 69. 70 CSS 70. 70 CSS { } 71. 70 CSS { } .menu__item { display: inline-block; } 72. XSLT 73. XSLT 72 74. XSLT 72 75. XSLT 72 - 76. XSLT 72 - 77. XSLT 73 bit.ly/vegedxslt 78. XSLT 74 79. XSLT 74 80. XSLT 74 81. XSLT 74 82. XSLT 74 83. BEMHTML 75 84. BEMHTML 75 JavaScript 85. BEMHTML 75 JavaScript BEM 86. BEMHTML 75 JavaScript BEM 87. JavaScript BEMHTML 76 88. JavaScript BEMHTML 76 (DSL), JavaScript 89. JavaScript BEMHTML 76 (DSL), JavaScript JavaScript 90. JavaScript BEMHTML 76 (DSL), JavaScript JavaScript JavaScript 91. JavaScript BEMHTML 76 (DSL), JavaScript JavaScript JavaScript 92. bem-core 77 bit.ly/bemcoretpl 93. BEMHTML 78 94. BEMHTML 78 bit.ly/bemhtmlref 95. 79 96. 79 { } 97. 79 { } .menu__item { display: inline-block; } 98. 79 { } .menu__item { display: inline-block; } block('menu').elem('item')( tag()('li') ) 99. BEM- HTML 80 100. BEMJSON BEMHTML HTML 81 101. BEMJSON 82 102. BEMHTML 83 103. HTML 84 104. 85 DOM ! style = display: inline-block; background-color: silver; ! ! ! .menu__item { display: inline-block; } BEM ! BEMJSON { block: 'menu' elem: 'item', tag: li' } BEMHTML block('menu').elem('item')( tag()('li') ) 105. BEMHTML. 86 106. BEMHTML. 86 HTML (, , ..) 107. BEMHTML. 86 HTML (, , ..) 108. BEMHTML. 86 HTML (, , ..) () 109. BEMHTML. 86 HTML (, , ..) () this.ctx 110. BEMHTML. 87 111. BEMHTML. 88 112. BEMHTML. 88 default 113. BEMHTML. 88 default tag HTML 114. BEMHTML. 88 default tag HTML js js 115. BEMHTML. 88 default tag HTML js js bem - 116. BEMHTML. 88 default tag HTML js js bem - cls 117. BEMHTML. 88 default tag HTML js js bem - cls mix - DOM- 118. BEMHTML. 88 default tag HTML js js bem - cls mix - DOM- jsAttrs HTML- js 119. BEMHTML. 88 default tag HTML js js bem - cls mix - DOM- jsAttrs HTML- js attrs HTML- 120. BEMHTML. 88 default tag HTML js js bem - cls mix - DOM- jsAttrs HTML- js attrs HTML- content HTML- 121. BEMHTML 89 122. BEMHTML 89 match(1, 2, 3)(); 123. BEMHTML 89 match(1, 2, 3)(); match( 1).match( 2)(1) match( 1).match( 3)(2) 124. BEMHTML 89 match(1, 2, 3)(); match( 1).match( 2)(1) match( 1).match( 3)(2) match(1)( match(2)(1), match(3)(2) ) 125. BEMHTML 90 126. BEMHTML 90 match(1, 2)() 127. BEMHTML 90 match(1, 2)() match(this.block === 'link', this._mode === 'tag', this.ctx.url )('a'); 128. BEMHTML 90 match(1, 2)() match(this.block === 'link', this._mode === 'tag', this.ctx.url )('a'); match(this.block === 'link') .match(this._mode === 'tag') .match(this.ctx.url)('a'); 129. - 91 130. - 91 { block: 'b-menu' } 131. - 91 { block: 'b-menu' } { elem: 'item' } 132. - 91 { block: 'b-menu' } { elem: 'item' } { block: 'b-link', mods: { pseudo: 'yes', color: 'green' } } 133. - 91 { block: 'b-menu' } { elem: 'item' } { block: 'b-link', mods: { pseudo: 'yes', color: 'green' } } { elem: 'item', elemMods: { selected: 'yes' } } 134. - 91 { block: 'b-menu' } { elem: 'item' } { block: 'b-link', mods: { pseudo: 'yes', color: 'green' } } { elem: 'item', elemMods: { selected: 'yes' } } { block: 'b-link', mix: [ { block: 'b-serp-item', elem: 'link' } ] } 135. HTML 92 136. HTML 92 { block: 'my-block', tag: 'img' } 137. HTML 92 { block: 'my-block', tag: 'img' } { block: 'my-block', tag: 'img', attrs: { src: ', alt: '' }} 138. HTML 92 { block: 'my-block', tag: 'img' } { block: 'my-block', tag: 'img', attrs: { src: ', alt: '' }} { block: 'my-block', cls: 'additional-class' } 139. HTML 92 { block: 'my-block', tag: 'img' } { block: 'my-block', tag: 'img', attrs: { src: ', alt: '' }} { block: 'my-block', cls: 'additional-class' } { block: page', tag: html', bem: false } 140. HTML 92 { block: 'my-block', tag: 'img' } { block: 'my-block', tag: 'img', attrs: { src: ', alt: '' }} { block: 'my-block', cls: 'additional-class' } { block: page', tag: html', bem: false } { block: my-block', js: true } 141. 93 { } { } { } 142. BEMHTML 94 bit.ly/bemhtmlref 143. Lets code BEMHTML 144. 96 145. 146. 147. data BEM- HTML 99 148. data BEMJSON 100 149. 101 150. priv.js 102 JavaScript 151. priv.js ? 103 152. priv.js ? 103 153. priv.js ? 103 154. priv.js ? 103 BEMHTML 155. BEMTREE 104 156. BEMTREE 104 157. BEMTREE 104 158. BEMTREE 104 159. BEMTREE 104 c BEMHTML 160. 105 161. BEMHTML BEMTREE 106 162. BEMHTML BEMTREE 106 163. BEMHTML BEMTREE 106 BEMTREE default, content 164. BEMHTML BEMTREE 106 BEMTREE default, content , 165. BEMTREE 107 BEM 166. BEMTREE 108 bit.ly/bemtree 167. Lets code BEMTREE 168. JavaScript + 169. 111 170. bem-core github.com/bem/bem-core ! bem-components github.com/bem/bem-components 112 171. ym github.com/ymaps/modules 113 172. BEM BEMHTML $ (jQuery) 114 173. BEM BEMHTML $ (jQuery) $.inherit $.observable $.identify $.debounce 115 174. BEM BEMHTML $ (jQuery) $.inherit $.observable $.identify $.debounce 116 modules 175. 117 176. 118 modules.dene('i-bem', ['inherit'], function(provide, inherit) { var BEM = inherit(/* */) provide(BEM) }) 177. 119 modules.require(['i-bem', 'jquery'], function(BEM, $) { /* , i-bem jquery */ }) 178. i-bem.js 179. i-bem.js? 121 180. i-bem.js 122 , 181. i-bem.js 123 , i-bem JavaScript 182. i-bem.js 124 , i-bem JavaScript jQuery API 183. i-bem.js? 125 184. i-bem.js 126 185. i-bem.js 127 186. i-bem.js 128 187. 129 i-bem.js? 188. i-bem.js bem-core/! ! ! ! common.blocks/! ! ! ! ! ! ! i-bem/! ! ! ! ! ! ! ! ! ! i-bem.vanilla.js! ! ! ! ! ! ! ! ! ! __dom/! ! ! ! ! ! ! ! ! ! ! ! ! i-bem__dom.js 130 189. i-bem.js bem-core/! ! ! ! common.blocks/! ! ! ! ! ! ! i-bem/! ! ! ! ! ! ! ! ! ! i-bem.vanilla.js! ! ! ! ! ! ! ! ! ! __dom/! ! ! ! ! ! ! ! ! ! ! ! ! i-bem__dom.js 131 190. i-bem.js bem-core/! ! ! ! common.blocks/! ! ! ! ! ! ! i-bem/! ! ! ! ! ! ! ! ! ! i-bem.vanilla.js! ! ! ! ! ! ! ! ! ! __dom/! ! ! ! ! ! ! ! ! ! ! ! ! i-bem__dom.js 132 191. JS- 192. 134 {! !!!!block: 'form'! } js- 193. 135 {! !!!!block: 'form',! !!!!js: true! } js- 194. 136 {! !!!!block: 'form',! !!!!js: { p1: 'v1', p2: 'v2', }! } js- 195. 137

js- 196. 138

js- 197. 139

js- 198. 140

js- 199. - 200. 142 BEMDOM.decl('form', {! /* */ }, {! /* */ }); 201. 143 BEMDOM.decl({! block: 'form', ! modName: 'type',! modVal: 'dialog'! }, {! /* */ }, {! /* */ }); 202. 144 BEMDOM.decl({! block: 'form', ! elem: 'control'! }, {! /* */ }, {! /* */ }); 203. 145 BEMDOM.decl({! block: 'form', ! elem: 'control',! modName: 'type', ! modVal: 'input'! }, {! /* */ }, {! /* */ }); 204. 146 BEMDOM.decl('form', {! onSetMod: {! !!!! disabled: function(modName, modVal) {! ! /* */ ! !!!! }! !!!!}! }); 205. 147 BEMDOM.decl({! block: 'dialog', ! baseBlock: 'form'! }, {! /* */ }, {! /* */ }); 206. 148 207. 149 BEMDOM.decl('form', { myMethod: function() { // this // this.__self // this.__self.myStaticMethod() // super-call this.__base() } }); 208. 150 BEMDOM.decl('form', { /* */ }, { myStaticMethod: function() { // this // super-call this.__base() } }); 209. 210. 152 211. 153 212. 154 213. 155 DOM- 214. 156 // this.findBlockInside('button') this.findBlockOutside('page') this.findBlockOn('dialog') 215. 157 // this.findBlockInside('button') this.findBlockOutside('page') this.findBlockOn('dialog') ! // this.findElem('control') this.elem('control') 216. 158 // this.findBlockInside('button') this.findBlockOutside('page') this.findBlockOn('dialog') ! // this.findElem('control') this.elem('control') ! // this.setMod('status', 'loading') this.hasMod('status', 'loading') this.getMod('status') this.delMod('status') 217. 159 DOM- 218. 160 DOM- BEM- 219. 161 DOM- BEM- 220. 162 DOM- BEM- 221. 163 // DOM- this.bindTo('submit', function() { /**/ }) this.unbindFrom('submit') 222. 164 // DOM- this.bindTo('submit', function() { /**/ }) this.unbindFrom('submit') ! // BEM- this.on('update', function() { /**/ }) this.un('update', function() { /**/ }) this.emit('update') 223. 224. 166

225. 167

226. 168

227. 169 BEMDOM.decl('menu', {! onSetMod: {! !!!! js: {! inited: function() {! /* */ }! !!!! }! !!!!}! }); 228. ! 170 229. ! 171 DOM- 230. ! 172 DOM- 231. ! 173 DOM- 232. ! 174 DOM- 233. Lets code! JavaScript 234. 176 235. 177 ^_^ -, project-stub bem-core bem-components bem-tools i-bem.js, BEMHTML, BEMTREE 236. 178 [email protected] @bem_ru @bem_en #b_ clubs.ya.ru/bem ! ___ groups/bem.info bem 237. 179 bit.ly/bemup-minsk-feedback 238. 180 [email protected] [email protected] [email protected] clubs.ya.ru/bem twitter.com/bem_ru facebook.com/groups/bem.info bem.info