БЭМ в дикой природе
Василий Чернов

01
Среда обитания
1. Атмосфера:
внутренние проекты и заказная разработка, Agile
2. География:
Москва, Оренбург, Новосибирск, Воронеж, Красноярск, Таганрог
3. Внешние факторы:
PHP, .NET, Java, 1С-Битрикс, Microsoft SharePoint

02
Многообразие видов

03
Естественные враги
1. устаревание документации
2. географическая распределенность
3. сложность совместной работы
4. непереносимость решений
5. PHP :(

04
Эволюционные изменения
• HTML — свой BEMXML
• CSS — классическая нотация записи CSS-классов,
разбиение на файлы блоков
• JS

05
Пишем HTML по БЭМ — BEMXML
• преобразовение БЭМ-дерева в DOM-дерево
• управление семантикой узлов
• простая система шаблонов
• возможность подключать XSLT-шаблоны (но их никто не пишет :)

Достаточно уметь писать XML и знать BEMXML-синтаксис
https://github.com/bivihoba/slcf-compiler
06
XML
Структура BEMXML-страницы
01. <page>
02.
<project>
03.
<include href="default-semantic.xml"/>
04.
<include href="templates.xml"/>
05.
</project>
06.
<default-semantic>
07.
<b:page-title tag="h1"/>
08.
</default-semantic>
09.
<templates>
10.
<p:page-title>Страница не найдена</p:page-title>
11.
<t:main-content>
12.
<p:page-title/>
13.
</t:main-content>
14.
</templates>
15.
<page-canvas>
16.
<p:layout/>
17.
</page-canvas>
18. </page>
Структура BEMXML-страницы
01. <page>
Подключаем общие файлы
02.
<project>
03.
<include href="default-semantic.xml"/>
04.
<include href="templates.xml"/>
05.
</project>
06.
<default-semantic>
07.
<b:page-title tag="h1"/>
08.
</default-semantic>
09.
<templates>
10.
<p:page-title>Страница не найдена</p:page-title>
11.
<t:main-content>
12.
<p:page-title/>
13.
</t:main-content>
14.
</templates>
15.
<page-canvas>
16.
<p:layout/>
17.
</page-canvas>
18. </page>
Структура BEMXML-страницы
01. <page>
02.
<project>
03.
<include href="default-semantic.xml"/>
04.
<include href="templates.xml"/>
05.
</project>
Определяем семантику
06.
<default-semantic>
07.
<b:page-title tag="h1"/>
08.
</default-semantic>
09.
<templates>
10.
<p:page-title>Страница не найдена</p:page-title>
11.
<t:main-content>
12.
<p:page-title/>
13.
</t:main-content>
14.
</templates>
15.
<page-canvas>
16.
<p:layout/>
17.
</page-canvas>
18. </page>
Структура BEMXML-страницы
01. <page>
02.
<project>
03.
<include href="default-semantic.xml"/>
04.
<include href="templates.xml"/>
05.
</project>
06.
<default-semantic>
07.
<b:page-title tag="h1"/>
08.
</default-semantic>
Объявляем шаблоны
09.
<templates>
10.
<p:page-title>Страница не найдена</p:page-title>
11.
<t:main-content>
12.
<p:page-title/>
13.
</t:main-content>
14.
</templates>
15.
<page-canvas>
16.
<p:layout/>
17.
</page-canvas>
18. </page>
Структура BEMXML-страницы
01. <page>
02.
<project>
03.
<include href="default-semantic.xml"/>
04.
<include href="templates.xml"/>
05.
</project>
06.
<default-semantic>
07.
<b:page-title tag="h1"/>
08.
</default-semantic>
09.
<templates>
10.
<p:page-title>Страница не найдена</p:page-title>
11.
<t:main-content>
12.
<p:page-title/>
13.
</t:main-content>
14.
</templates>
Выводим всё на страницу
15.
<page-canvas>
16.
<p:layout/>
17.
</page-canvas>
18. </page>
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>
BEMXML-разметка
Блок
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>

Элементы блока
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
элементу можно назначить блок вручную
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>

Модификация блока
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
Можно примешать блок
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>

... или элемент блока
BEMXML-разметка
01. <b:product>
02.
<m:viewtype val="complete"/>
03.
<a:article>
Можно добавлять модификации
04.
<m:viewtype val="s1"/>
05.
<m:content val="product"/>
06.
</a:article>
07.
<e:details>
08.
<a:section>
на примешанные блоки
09.
<m:viewtype val="s1-details"/>
10.
<m:content val="product-details"/>
11.
</a:section>
12.
<e:header block="section">
13.
<e:title>
14.
<a:title block-of="article"/>
15.
<a:page-title/>
Результаты
• Актуальная документация
• Ускорение процесса верстки
• Быстрое внедрение в работу
• Навязывание БЭМ-мышления

08
Как мы пишем CSS по БЭМ
• Каскад
• Миксы
• Блок vs. модификатор
• Сочетание модификаторов
• Блоки на файловой системе

09
Блок + элемент блока
01. .b-region
02.

.b-region __title {

margin-right: 20px;

03. }
Излишне, такая связь заложена на уровне синтаксиса

10
Модификатор блока + элемент
.b-list_type_simple .b-list__item {}
01. <ul class="b-list b-list_type_simple">
02.

<li class=" b-list__item ">

03.

<ol class="b-list b-list_type_numeric">

04.

<li class=" b-list__item ">
Приемлимо, но могут быть неприятные эффекты
11
Сущности из разных блоков
.b-article .b-link {...} /* «межблочный каскад» */
неприемлимо, но по-разному — зависит от семантики:

01.

.b-article .b-link {}

02.

.b-pagination .b-link {}

12
Полегче с миксами!
• «узаконенный каскад»
• микс != глобальный модификатор

.b-inline {display:inline;}
<h4 class="b-product__title b-inline "/>
Блок должен иметь ценность сам по себе.
13
01. <article class=" b-article
b-product
02.

b-article_content_product
b-product_type_sale ">

<header class=" b-article__header "/>

03.

<h3 class=" b-product__title "/>Title</h3>

04.

</header>

05.

<div class=" b-article__content

b-product__descriptio

01. .b-product_type_sale .b-product__title {}
02. .b-article_content_product .b-article__header {}
14
15
16
Меньше блоков
Вместо трех блоков:
b-span1

b-span2

b-span3

один с модификаторами
b-span_ size_1

17

b-span_ size_2 b-span_ size_3
Работа с библиотекой блоков
Где же этот ящик...
Больше блоков
плюс сущность
.b-menu_type_main -> b-main-menu
минус связь
.b-menu_type_main .b-menu__item -> b-main-menu__item

20
Больше типов. Общие модификаторы
• type - ключевые свойства и особенности
• layout - раскладка
• viewtype - представление
• viewtype-theme - тема/скин в пределах выбранного viewtype
• content - содержимое
• context - контекст

21
Каскад модификаторов
• .b-menu__item
• .b-menu__item_state_selected
• .b-menu_ type _meta. b-menu__item_state_selected
• .b-menu_ viewtype _ribbon .b-menu__item_state_selected
• .b-menu_ content _products .b-menu__item_state_selected

22
Постепенное выделение блоков
на файловой системе
• .b-button.css
• .b-button_state.css
• .b-button_state_pressed.css

23
Результаты
• Минимальные затраты на инфраструктуру
• Всегда «знакомый» код
• Возможность оценивать качество проектирования

24
У нас есть план
• доработка нашей библиотеки блоков
• i-bem.js
• миграция на bem-tools/enb
• ...
• PROFIT!

25
Василий Чернов
руководитель группы верстки,
департамент разработки интернет-проектов, Softline
vasiliy.chernov@softline.ru
@bivihoba

cлайды

Василий Чернов — БЭМ в дикой природе

  • 1.
    БЭМ в дикойприроде Василий Чернов 01
  • 2.
    Среда обитания 1. Атмосфера: внутренниепроекты и заказная разработка, Agile 2. География: Москва, Оренбург, Новосибирск, Воронеж, Красноярск, Таганрог 3. Внешние факторы: PHP, .NET, Java, 1С-Битрикс, Microsoft SharePoint 02
  • 3.
  • 4.
    Естественные враги 1. устареваниедокументации 2. географическая распределенность 3. сложность совместной работы 4. непереносимость решений 5. PHP :( 04
  • 5.
    Эволюционные изменения • HTML— свой BEMXML • CSS — классическая нотация записи CSS-классов, разбиение на файлы блоков • JS 05
  • 6.
    Пишем HTML поБЭМ — BEMXML • преобразовение БЭМ-дерева в DOM-дерево • управление семантикой узлов • простая система шаблонов • возможность подключать XSLT-шаблоны (но их никто не пишет :) Достаточно уметь писать XML и знать BEMXML-синтаксис https://github.com/bivihoba/slcf-compiler 06
  • 7.
  • 8.
    Структура BEMXML-страницы 01. <page> 02. <project> 03. <includehref="default-semantic.xml"/> 04. <include href="templates.xml"/> 05. </project> 06. <default-semantic> 07. <b:page-title tag="h1"/> 08. </default-semantic> 09. <templates> 10. <p:page-title>Страница не найдена</p:page-title> 11. <t:main-content> 12. <p:page-title/> 13. </t:main-content> 14. </templates> 15. <page-canvas> 16. <p:layout/> 17. </page-canvas> 18. </page>
  • 9.
    Структура BEMXML-страницы 01. <page> Подключаемобщие файлы 02. <project> 03. <include href="default-semantic.xml"/> 04. <include href="templates.xml"/> 05. </project> 06. <default-semantic> 07. <b:page-title tag="h1"/> 08. </default-semantic> 09. <templates> 10. <p:page-title>Страница не найдена</p:page-title> 11. <t:main-content> 12. <p:page-title/> 13. </t:main-content> 14. </templates> 15. <page-canvas> 16. <p:layout/> 17. </page-canvas> 18. </page>
  • 10.
    Структура BEMXML-страницы 01. <page> 02. <project> 03. <includehref="default-semantic.xml"/> 04. <include href="templates.xml"/> 05. </project> Определяем семантику 06. <default-semantic> 07. <b:page-title tag="h1"/> 08. </default-semantic> 09. <templates> 10. <p:page-title>Страница не найдена</p:page-title> 11. <t:main-content> 12. <p:page-title/> 13. </t:main-content> 14. </templates> 15. <page-canvas> 16. <p:layout/> 17. </page-canvas> 18. </page>
  • 11.
    Структура BEMXML-страницы 01. <page> 02. <project> 03. <includehref="default-semantic.xml"/> 04. <include href="templates.xml"/> 05. </project> 06. <default-semantic> 07. <b:page-title tag="h1"/> 08. </default-semantic> Объявляем шаблоны 09. <templates> 10. <p:page-title>Страница не найдена</p:page-title> 11. <t:main-content> 12. <p:page-title/> 13. </t:main-content> 14. </templates> 15. <page-canvas> 16. <p:layout/> 17. </page-canvas> 18. </page>
  • 12.
    Структура BEMXML-страницы 01. <page> 02. <project> 03. <includehref="default-semantic.xml"/> 04. <include href="templates.xml"/> 05. </project> 06. <default-semantic> 07. <b:page-title tag="h1"/> 08. </default-semantic> 09. <templates> 10. <p:page-title>Страница не найдена</p:page-title> 11. <t:main-content> 12. <p:page-title/> 13. </t:main-content> 14. </templates> Выводим всё на страницу 15. <page-canvas> 16. <p:layout/> 17. </page-canvas> 18. </page>
  • 13.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/>
  • 14.
    BEMXML-разметка Блок 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/>
  • 15.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/> Элементы блока
  • 16.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> элементу можно назначить блок вручную 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/>
  • 17.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/> Модификация блока
  • 18.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> Можнопримешать блок 03. <a:article> 04. <m:viewtype val="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/>
  • 19.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> 04. <m:viewtypeval="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/> ... или элемент блока
  • 20.
    BEMXML-разметка 01. <b:product> 02. <m:viewtype val="complete"/> 03. <a:article> Можнодобавлять модификации 04. <m:viewtype val="s1"/> 05. <m:content val="product"/> 06. </a:article> 07. <e:details> 08. <a:section> на примешанные блоки 09. <m:viewtype val="s1-details"/> 10. <m:content val="product-details"/> 11. </a:section> 12. <e:header block="section"> 13. <e:title> 14. <a:title block-of="article"/> 15. <a:page-title/>
  • 21.
    Результаты • Актуальная документация •Ускорение процесса верстки • Быстрое внедрение в работу • Навязывание БЭМ-мышления 08
  • 22.
    Как мы пишемCSS по БЭМ • Каскад • Миксы • Блок vs. модификатор • Сочетание модификаторов • Блоки на файловой системе 09
  • 23.
    Блок + элементблока 01. .b-region 02. .b-region __title { margin-right: 20px; 03. } Излишне, такая связь заложена на уровне синтаксиса 10
  • 24.
    Модификатор блока +элемент .b-list_type_simple .b-list__item {} 01. <ul class="b-list b-list_type_simple"> 02. <li class=" b-list__item "> 03. <ol class="b-list b-list_type_numeric"> 04. <li class=" b-list__item "> Приемлимо, но могут быть неприятные эффекты 11
  • 25.
    Сущности из разныхблоков .b-article .b-link {...} /* «межблочный каскад» */ неприемлимо, но по-разному — зависит от семантики: 01. .b-article .b-link {} 02. .b-pagination .b-link {} 12
  • 26.
    Полегче с миксами! •«узаконенный каскад» • микс != глобальный модификатор .b-inline {display:inline;} <h4 class="b-product__title b-inline "/> Блок должен иметь ценность сам по себе. 13
  • 27.
    01. <article class="b-article b-product 02. b-article_content_product b-product_type_sale "> <header class=" b-article__header "/> 03. <h3 class=" b-product__title "/>Title</h3> 04. </header> 05. <div class=" b-article__content b-product__descriptio 01. .b-product_type_sale .b-product__title {} 02. .b-article_content_product .b-article__header {} 14
  • 28.
  • 29.
  • 30.
    Меньше блоков Вместо трехблоков: b-span1 b-span2 b-span3 один с модификаторами b-span_ size_1 17 b-span_ size_2 b-span_ size_3
  • 31.
  • 32.
  • 33.
    Больше блоков плюс сущность .b-menu_type_main-> b-main-menu минус связь .b-menu_type_main .b-menu__item -> b-main-menu__item 20
  • 34.
    Больше типов. Общиемодификаторы • type - ключевые свойства и особенности • layout - раскладка • viewtype - представление • viewtype-theme - тема/скин в пределах выбранного viewtype • content - содержимое • context - контекст 21
  • 35.
    Каскад модификаторов • .b-menu__item •.b-menu__item_state_selected • .b-menu_ type _meta. b-menu__item_state_selected • .b-menu_ viewtype _ribbon .b-menu__item_state_selected • .b-menu_ content _products .b-menu__item_state_selected 22
  • 36.
    Постепенное выделение блоков нафайловой системе • .b-button.css • .b-button_state.css • .b-button_state_pressed.css 23
  • 37.
    Результаты • Минимальные затратына инфраструктуру • Всегда «знакомый» код • Возможность оценивать качество проектирования 24
  • 38.
    У нас естьплан • доработка нашей библиотеки блоков • i-bem.js • миграция на bem-tools/enb • ... • PROFIT! 25
  • 39.
    Василий Чернов руководитель группыверстки, департамент разработки интернет-проектов, Softline vasiliy.chernov@softline.ru @bivihoba cлайды