Василий Чернов — БЭМ в дикой природе
DESCRIPTION
В докладе я расскажу о том, как в Softline пришли к БЭМ, который используется в HTML/CSS-вёрстке уже около трёх лет. Для БЭМ у нас есть собственный фреймворк (ядро XML+XSLT), но мы всегда хотим двигаться вперёд — и расскажем о своих планах. Поговорим о возникавших проблемах, интересных решениях, об особенностях построения процессов в нашей компании. Я покажу, как мы используем bem-tools, как пишем CSS по БЭМ-методу, а также разберу несколько примеров исходного кода XML и CSS.TRANSCRIPT
Среда обитания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
XMLXML
Структура BEMXML-страницы<page> <project> <include href="default-semantic.xml"/> <include href="templates.xml"/> </project> <default-semantic> <b:page-title tag="h1"/> </default-semantic> <templates> <p:page-title>Страница не найдена</p:page-title> <t:main-content> <p:page-title/> </t:main-content> </templates> <page-canvas> <p:layout/> </page-canvas></page>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.17.18.
Подключаем общие файлы
Структура BEMXML-страницы<page> <project> <include href="default-semantic.xml"/> <include href="templates.xml"/> </project> <default-semantic> <b:page-title tag="h1"/> </default-semantic> <templates> <p:page-title>Страница не найдена</p:page-title> <t:main-content> <p:page-title/> </t:main-content> </templates> <page-canvas> <p:layout/> </page-canvas></page>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.17.18.
Определяем семантику
Структура BEMXML-страницы<page> <project> <include href="default-semantic.xml"/> <include href="templates.xml"/> </project> <default-semantic> <b:page-title tag="h1"/> </default-semantic> <templates> <p:page-title>Страница не найдена</p:page-title> <t:main-content> <p:page-title/> </t:main-content> </templates> <page-canvas> <p:layout/> </page-canvas></page>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.17.18.
Объявляем шаблоны
Структура BEMXML-страницы<page> <project> <include href="default-semantic.xml"/> <include href="templates.xml"/> </project> <default-semantic> <b:page-title tag="h1"/> </default-semantic> <templates> <p:page-title>Страница не найдена</p:page-title> <t:main-content> <p:page-title/> </t:main-content> </templates> <page-canvas> <p:layout/> </page-canvas></page>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.17.18.
Выводим всё на страницу
Структура BEMXML-страницы<page> <project> <include href="default-semantic.xml"/> <include href="templates.xml"/> </project> <default-semantic> <b:page-title tag="h1"/> </default-semantic> <templates> <p:page-title>Страница не найдена</p:page-title> <t:main-content> <p:page-title/> </t:main-content> </templates> <page-canvas> <p:layout/> </page-canvas></page>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.16.17.18.
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Блок
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Элементы блока
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
элементу можно назначить блок вручную
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Модификация блока
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Можно примешать блок
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
... или элемент блока
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Можно добавлять модификации
на примешанные блоки
BEMXML-разметка<b:product> <m:viewtype val="complete"/> <a:article> <m:viewtype val="s1"/> <m:content val="product"/> </a:article> <e:details> <a:section> <m:viewtype val="s1-details"/> <m:content val="product-details"/> </a:section> <e:header block="section"> <e:title> <a:title block-of="article"/> <a:page-title/>
01.02.03.04.05.06.07.08.09.10.11.12.13.14.15.
Результаты• Актуальная документация
• Ускорение процесса верстки
• Быстрое внедрение в работу
• Навязывание БЭМ-мышления
08
Как мы пишем CSS по БЭМ• Каскад
• Миксы
• Блок vs. модификатор
• Сочетание модификаторов
• Блоки на файловой системе
09
Блок + элемент блока.b-region .b-region __title {
margin-right: 20px;
}
Излишне, такая связь заложена на уровне синтаксиса
01.
02.
03.
10
Модификатор блока + элемент.b-list_type_simple .b-list__item {}
<ul class="b-list b-list_type_simple">
<li class=" b-list__item ">
<ol class="b-list b-list_type_numeric">
<li class=" b-list__item ">
Приемлимо, но могут быть неприятные эффекты
01.
02.
03.
04.
11
Сущности из разных блоков.b-article .b-link {...} /* «межблочный каскад» */
неприемлимо, но по-разному — зависит от семантики:
.b-article .b-link {}
.b-pagination .b-link {}
01.
02.
12
Полегче с миксами!• «узаконенный каскад»
• микс != глобальный модификатор
.b-inline {display:inline;}
<h4 class="b-product__title b-inline "/>
Блок должен иметь ценность сам по себе.
13
<article class=" b-article b-article_content_product
b-product b-product_type_sale ">
<header class=" b-article__header "/>
<h3 class=" b-product__title "/>Title</h3>
</header>
<div class=" b-article__content b-product__description
.b-product_type_sale .b-product__title {}
.b-article_content_product .b-article__header {}
01.
02.
03.
04.
05.
01.
02.
14
15
16
Меньше блоковВместо трех блоков:
b-span1 b-span2 b-span3
один с модификаторами
b-span_ size_1 b-span_ size_2 b-span_ size_3
17
Работа с библиотекой блоков
Где же этот ящик...
Больше блоковплюс сущность
.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
@bivihoba
cлайды