Как сверстать сайт вручную «по-БЭМ» без классов "block__element__element", и на реальном примере со всеми его проблемами, а не меню-пункт_меню-ссылочка, как вы видели раньше. Без BEMJSON, BEM Tools, но с миксованием, модификаторами и разбором ошибок.
Я знаком с БЭМ давно, и все эти годы встречался с множеством заблуждений и стереотипов в использовании. В докладе постарался развеять популярные мифы и рассказал о своём трехлетнем опыте внедрения и использования БЭМ и связанным с этим наступании на грабли.
WebCamp: Front-end Developers Day
Одесса
4 июля 2015
#WebCampOdessa
#OIW2015
#WebCamp2015
Видео: https://youtu.be/hTmxbJF2Tts
Слайды: http://delka.github.io/talks/webcamp/2015/bem/
1. Пишем БЭМ правильно
Классы типа block__elem__elem__elem говорят о том,
что верстальщик ничего не понял в #b_.
09:16 - 21 ноября 2013 Ukraine, Ukraine
Vitaly HarisoVitaly Harisovv
@harisov
Читать
55 РЕТВИТОВ 22 ТВИТОВ В ИЗБРАННОМ
ОтветитьРетвитнутьВ избранное
2. В исходниках этой презентации
спрятались подсказки!
В комментах html написаны тезисы доклада и комментарии к слайдам
требующим пояснений.
Презентация: delka.github.io/talks/2015/frontendweekend-bem/
2
10. Код, который тяжело поддерживать
Что в этом коде относится к классу user ?
<div class="media user premium">
<img class="img photo avatar" src="" />
<p class="body bio">...</p>
</div>
01.
02.
03.
04.
10
11. … и код, который ЛЕГКО поддерживать
Если мы перепишем этот код на BEM CSS, то все будет понятно просто
из имён классов!
<div class="media user -- premium">
<img class=" media__ img user __ photo avatar" src="" />
<p class=" media__ body user __ bio">...</p>
</div>
01.
02.
03.
04.
11
15. Full stack BEM?
Когда он будет вам нужен — вы это сами поймёте.
Это будет момент, когда вам надоест писать html руками и вы захотите
его генерировать.
15
30. БЭМ пугал когда он вышел. Там была простыня
текста в документации на не очень прямом
английском про философию.
10:06 - 6 августа 2015
РРазрабоазработчиктчик
@jsunderhood
Читать
11 ТВИТ В ИЗБРАННОМ
ОтветитьРетвитнутьВ избранное
Что я имел ввиду - авторы БЭМ не смогли его
продать. В том числе из-за сложной и не очень
удобной документации, ИМХО.
10:06 - 6 августа 2015
РРазрабоазработчиктчик
@jsunderhood
Читать
11 РЕТВИТОВ 44 ТВИТОВ В ИЗБРАННОМ
ОтветитьРетвитнутьВ избранное
30
31. Даже разработчики Google Material Design не смогли с первого
раза правильно написать имена классов по БЭМ :)
35. Независимый блок
НБ или просто блок, это самодостаточный элемент страницы,
который при перемещении в другое место на странице или на другую
страницу не теряет своей самодостаточности.
БЭМ.Форум, Независимый блок
“
35
36. Обновленное определение блока
Логически и функционально независимый компонент страницы, аналог
компонента в Web Components. Блок инкапсулирует в себе поведение
(JavaScript), шаблоны, стили (CSS) и другие технологии реализации.
Независимость блоков обеспечивает возможность их повторного
использования, а также удобство в разработке и поддержке проекта.
bem.info, Методология
“
36
37. Правила независимости блока
1. для описания элемента используется class, но не id
2. каждый блок имеет префикс
3. в таблице стилей нет классов вне блоков
БЭМ.Форум, История создания БЭМ (часть первая)“
37
38. Как его таким написать?
Просто писать стили тупо на каждый блок.
БЭМ хорош тем, что позволяет не забивать голову ерундой с каскадом,
а сосредоточиться на семантике и логике кода.
А с препроцессорами БЭМ позволяет писать еще и очень чистый и
логичный код.
38
39. Как проверить?
Просто навести на блок в инспекторе кода.
У него не должно быть каскада.
На самом деле каскад допускается, но его следует избегать.
39
42. Элемент
Элемент – это часть блока, отвечающая за отдельную функцию.
Он может находиться только в составе блока и не имеет смысла в
отрыве от него.
bem.info, Методология
Можете себе представить что это как папки в файловой системе,
способ организации кода, чтобы было понятно, что к чему относится.
“
42
49. БЭМ дерево — чистая логика
БЭМ-дерево не зависит ни от чего, даже от размещения в документе.
БЭМ-дерево не привязано к визуальному представлению блоков, оно
отображает только логику, это и есть новый уровень семантики!
49
52. Я тоже раньше так писал
.form-buy-results__to-city__slider__tab__column_buy
Так делать нельзя
Чувак, это css-селектор или ты придумывал полное
имя для фэнтезийного короля?
3:56 PM - 22 Apr 2015
ААлеклексей Сергиенксей Сергиенкоо
@lehazyo_chatik
Follow
11 RETWEET 11 FAVORITE
ReplyRetweetFavorite
52
54. А в CSS
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
01.
02.
03.
04.
54
55. Элемент у элемента?
Если вам нужно сделать элемент у элемента, значит вам нужно:
• или создать новый блок
• или сделать ваше БЭМ-дерево с одинарной вложенностью
элементов
55
56. Есть 2 варианта как это переписать
<div class="block">
<div class="block __elem1 ">
<div class="block __elem1__elem2 "></div>
</div>
</div>
01.
02.
03.
04.
05.
56
64. Попытка вложить имя элемента в имя блока
Чтоб «схитрить» и «как-будто не вложить», написать не
.block__el1__el2 а .block el1 __el2 или
.block__el1 el2 . Так нельзя.
.block {}
.block el1 {}
.block el1 __el2 {}
Будут проблемы при переносе
01.
02.
03.
64
65. Будут проблемы при переносе
Попытались перенести «странный элемент» в другое место - получили
элемент что завис «в воздухе» без блока-родителя
<div class=' someblock '>
<div class=' blockel1 __el2'></div>
</div>
Так можно делать только если .blockelem сохранит логический
смысл при переносе в другой блок.
01.
02.
03.
65
66. element > element нельзя в CSS, но
можно в HTML!
Обратите внимание - вы не можете вкладывать элементы в элементы
в CSS, но можете и должны вкладывать элементы в элементы в HTML!
DOM-дерево и БЭМ-дерево могут быть разными.
66
67. Запрет есть исключительно про
нейминг!
БЭМ-дерево на то и дерево, что поддерживает вложенность, поэтому
в БЭМ-дереве, разумеется, разрешается вкладывать элементы в
элементы, блоки в блоки, блоки в элементы.
Vladimir Grinenko, @tadatuta
“
67
75. Бьём на максимально атомарные
блоки!
NB: это и есть суть БЭМ, то, что многие не понимают.
Погружаясь вглубь DOM, нужно стараться создавать новые и новые
блоки, а не строить связи родитель__элемент__элемент .
75
76. Вспоминаем как мы это делаем:
<div class="block1">
<div class=" block1__elem1 block2 ">
<div class=" block2 __elem1"></div>
</div>
</div>
01.
02.
03.
04.
05.
76
79. Миксование создаст связь между
блоками!
В этой DOM-ноде смешиваются стили от 2-х разных блоков:
• от одного ( .b-blog__item ) — стили раскладки,
позиционирование,
• а от второго ( .b-post ) — внешний вид самого блока.
Эти стили объединяются в одном html-элементе и создают таким
образом связи между блоками.
79
80. CSS: как правильно вкладывать блоки
в блоки?
.b-blog {
// блок
@at-root .b-post {
// ещё один блок
}
}
01.
02.
03.
04.
05.
06.
80
81. Скомпилируется в:
. b-blog {
/* стили блока */
}
. b-post {
/* ещё один блок */
}
01.
02.
03.
04.
05.
06.
81
82. Мы написали вариант #1: микс
элемента родителя + новый блок
Позиционирование — на элементе родителя и блоке родителя, стили
блока — на новом блоке.
<div class=" b-blog ">
<div class=" b-blog_item b-post ">
</div>
</div>
01.
02.
03.
04.
82
84. #2: Микс блоков и сетки
Позиционирование — на классах сетки, стили блоков — на самих
блоках.
<div class="b-blog b-grid ">
<div class=" b-grid__col b-post ">
</div>
</div>
01.
02.
03.
04.
84
85. #2.1: Не жалеем div: блоки внутри
сетки
Позиционирование — на классах сетки, стили блоков — на самих
блоках.
<div class="b-blog">
<div class=" b-grid ">
<div class=" b-grid__col ">
<div class=" b-post ">
</div>
</div>
</div>
01.
02.
03.
04.
05.
06.
07.
85
86. #3: Блоки-врапперы ( l-l-, h-h-)
Позиционирование — на блоках-врапперах.
Связей между блоками (блок—элемент) больше нет!
Яндекс НЕ рекомендует! Но этот вариант часто встречается в жизни.
<div class=" l- blog">
<div class=" b- blog">
<div class=" l- post">
<div class=" b- post">
</div>
</div>
01.
02.
03.
04.
05.
06.
86
87.
88.
89.
90. Можно добавить микроформатов/
микроданных
Это не нужно для БЭМ, просто я люблю микроформаты, Гугл любит
микрофрматы и Яндекс тоже любит микроформаты :) Классно что мы
можем добавлять любые имена классов куда-угодно, все стили у нас —
только на БЭМ-классах.
90
95. 6 видов
1. Модификатором
• модификатором блока
• модификатором элемента
2. Контекстом (т.е. каскадом от блока выше)
3. Уровнем переопределения (добавлением-перезаписью файла
стилей)
4. Миксованием (добавлением классов других блоков)
• включая глобальный класс
95
97. Модификаторы для элементов, можно?
Если речь идет о простых правках, типа «активный пункт меню», то да,
можно:
<a class="menu__link menu__link _state_active ">
97
98. Булевые модификаторы
Кстати в таких простых случаях, можно писать модификаторы просто
одним словом:
<a class="menu__link menu__link _active ">
98
99.
100. Но подумайте, может это новый блок?
В случае ручной верстки, это сигнал об ошибках в вашей логике
разбиения на блоки. Признак неудачного проектирования
родительского блока. Если вам нужен модификатор на элемент — вам
Что вы думаете о модификаторах на элементы? #b_
28 ноябряIgor ZIgor Zenichenich @delaz
@delaz ГРЕШНОВАТО
11:56 - 29 ноября 2014
БЭМБЭМ
@bem_xxx
Читать
11 РЕТВИТ ИЗБРАННОЕ: 11
ОтветитьРетвитнутьВ избранное
100
104. 2. Повышение специфичности
В html как-будто всё ok:
<div class="block">
<div class="block__el">
А на деле сели в машину и сгорели:
/* CSS */
.block .block__el {}
01.
02.
01.
02.
104
105. 3. Стили вне блоков
<ul class="menu checkoutForm big myfuckingclass-bold ">
105
106. Почему это ошибки?
Да потому что из-за этого потом тяжелей вносить правки и сложно
переместить блок в другое место.
106
108. Проблемы со стилями:
1. CSS Frameworks
2. Инлайн стили
3. !important
4. Чрезмерно увеличенный вес селектора
5. Позиция в очереди подключения
108
109. Ошибки разработчиков:
6. Элемент элемента
7. Элемент вне блока
8. Контекстная зависимость блоков
9. Контекстная зависимость элемента
10. Наглый модификатор элемента (кроме самого себя трогает еще и
другие элементы этого же блока)
11. Блок, вложенный в себя
12. Использование стилевых классов в JS
109
110. Ошибки разработчиков:
13. Использование холстеров «как-бутстрап»: <ul class="b-list
h-mt-20 h-mb-50 h-pointer h-left h-colorred">
14. Неиспользование холстеров (модификаторы --float_left )
15. Единоразовые элементы (создание одинаковых элементов с
разными именами типа .list__item1 , .list__item2 ,…)
16. Oldschool reborn (высокая специфичность и класс только на блоке)
17. Looooooooong naming
18. Модификация элементами (смена имени элемента вместо
добавления модификатора)
110
112. Вывести текст из WYSIWYG?
Как назначаются стили для типографики? Не будешь же назначать
каждому тегу какой-то класс?
Artur Kornakov, @fliptheweb
“
112
113. Добавить .b-text.b-text блоку родителю
И использовать каскад.
.b-text h2 {}
.b-text p {}
.b-text img {}
.b-text ul li {}
Конечно при большом желании можно настроить визивиг, тот же
TinyMCE, чтоб он добавлял нужные имена классов в тегах из визивига.
01.
02.
03.
04.
113
114. Как писать BEM CSS в Saas
.b-list {
/* стили блока */
//…
&__ item {
/* стили элемента */
}
&__ link {
/* элемент #2… */
}
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
114
124. Как «правильно» модифицировать
блоки (внешний вид) от контекста?
1. Можно юзать каскад, но это тонкая работа — для случая «перебить
чуть-чуть стилей, ведь этот блок нам не понадобится переносить в
изменённом виде куда-то отдельно».
2. Добавить модификатор блоку — просто и надежно, но не создает
логической связи между блоком-родителем и вложенным в него
блоком, что должен изменятся.
3. Использовать миксование: создать элемент родителя, навесить на
него нужные стили и смиксовать с вложенным блоком.
124
126. Пример переверстки по БЭМ
(упрощенный)
• Было: http://net-craft.com/old
• Стало: http://net-craft.com/
• http://net-craft.com/wp-content/themes/netcraft/dev/sass/
main.scss
126
127. БЭМ это фреймворк для создания фреймворков.
14:50 - 12 июля 2015 Ukraine, Ukraine
Vitaly HarisoVitaly Harisovv
@harisov
Читать
33 РЕТВИТОВ 11 ТВИТОВ В ИЗБРАННОМ
ОтветитьРетвитнутьВ избранное
Диалекты БЭМ
128. Вот это вот всё на 5 минут:
• Префиксы (b-)
• Пространства имен (BEMIT)
• Стиль Гарри Робертса, camelCase и «без подчеркиваний»
• Сокращённые модификаторы (стиль „No-namespace“)
• JS-блоки
• OPOR
• BEViS
• Google MDL
• BEM project-stub HTML edition
128
130. Префиксы
Были в раннем БЭМ. Сейчас пропагандируются Гарри Робертсом и
используются многими не-Яндекс разработчиками. Используются для
создания своего пространства имен и логического разделения блоков.
130
131. BEMIT: Пространства имен
Продвинутое использование префиксов и суффиксов от Гарри
Робертса. Попытка описать взаимосвязь между независимыми
блоками с точки зрения SMACSS и OOCSS.
131
132. Стиль Гарри Робертса
Многим нравится зарубежный формат модификаторов, через „--“, он
читабельней.
<a class="block-name__element-name --state_active ">
132
133. Стиль camelCase
А через camelCase – ещё читабельней!
<a class=" blockName__elementName --state_active">
133
134. Стиль без подчеркиваний
Некоторые идут ещё дальше и заменяют „__“ на „-“. camelCase
единственный гарантирует что вы поймете где блок, а где элемент.
<a class=" blockName-elementName --state_active">
134
137. Но такие имена классов тяжело читать
<div class="block-name block-name_key1_val1 block-
name_key2_val2 block-name_key3_val3 ">
Нет дуракоустойчивости, модификатор могут перенести без блока:
<div class=" block-name_key1_val1 some-another-
block">
Хочется так:
<div class="block-name -key1_val1 -key2_val2 -
137
138. Сокращенные модификаторы
Зарубежом их назвали „Individual modifiers: a shorter syntax“. У нас
перевели как «Обособленные модификаторы: сокращенный
синтаксис». Яндекс в официальной документации называет их «Стиль
No-namespace».
<div class="blockName__elem -key_value ">
.blockName {
&__elem {
& .-key_value {
}
01.
02.
03.
04.
05.
138
139. — Теряем миксы блоков с
модификаторами!
— Не можем использовать Full BEM
Stack!
140. Решением может быть запись
модификаторов в столбик
<div class="block-name block-name_key1_value1
block-name_key2_value2 block-name_key3_value3 ">
<!-- VS -->
<div class="block-name
block-name_key1_value1
block-name_key2_value2
block-name_key3_value3 ">
А ещё можно юзать Jade, а в Яндексе вообще не пишут html-код
01.
02.
03.
04.
05.
140
141. JS-блоки
$(' .js- fancybox').fancybox();
Это миксование css-блока и js-блока на одной dom-ноде.
Канонический БЭМ считает, что они не нужны, т.к. js-функционал нет
смысла отделять от блока. Гарри Робертс и не-Яндекс разработчики их
активно используют и пропагандируют: т.к. разделение позволяет
легко копировать css-блок без связанного с ним JS.
141
143. Альтернативные реализации: BEViS
Диалект БЭМ, с более строгими правилами для максимальной
надежности верстки, придуманный Вадимом Макишвили для
Яндекс.Карт.
143
146. Вы можете создавать свои гайдлайны
БЭМ дает лишь базовый набор правил, конкретную реализацию и
синтаксис вы выбираете сами.
• Harry Roberts
• iDeus
• Artem Sapegin
• CodeRiver (Yuriy Artyukh, cssing.org.ua)
• AzaGroup
146
149. БЭМ включает в себя много техник
Кое-что мы с вами обсудили/упомянули:
• почему нельзя вкладывать блоки
• bem-tools и альтернативные тулзы для упрощенного написания БЭМ-
нейминга в HTML:
• BEML — html-препроцессор для BEM
• posthtml-bem — тоже самое, но через PostHTML
• bemto — миксины для написания BEM в Jade
• миксование
• зачем нужны пространства имен/префиксы (включая js- блоки)
149
150. Но многое осталось за кадром
• Я не рассказал вам как разбивать блоки на файлы и складывать в
файловой системе
• почему не нужно использовать не использовать @extend s Sass
• о i-bem.js
• и об абстрактных блоках (i-)
• …контекстных блоках (m-)
• …холдер-блоках (h-)
• …уровнях переопределения
• …глобальных модификаторах
• …и про историю BEM — почему все так?
150
151. Читать дальше
• Cоветы от ведущих БЭМ-разработчиков: ошибки и best practices
• BEM Quick Start Guide — БЭМ: UnOfficial Team
• Мажорный релиз новой документации — БЭМ: Яндекс Team
• Full BEM Stack в HTML — Владимир Гриненко
• Классификация ошибок BEM CSS (со стр. 50) — Александр Корецкий
@n2j7
• Material Design Lite CSS — Google
• i-bem.js
• варианты использования префиксов от Гарри Робертса
• BEMIT — Harry Roberts
151
152. …и дальше
• что такое блок, префикс b- и что такое независимый блок
• контекстные блоки (темы) (раздел «Внутри контекстного блока»)
• layout-блоки и холдер-блоки
• как позиционировать БЭМ-блоки относительно друг друга
• абстрактные блоки (раздел „i-, от include“) и их реализация в Sass
через %extend-only-selector+extend или лучше через mixin+include
• уровни переопределения (раздел «Модификация файлами») и
структура блоков на файловой системе
• глобальные модификаторы
• Откуда взялся зарубежный синтаксис модификаторов и js-классы —
152
153. Спасибо!
Igor Zenich
EPAM, ex. iDeus
• delka.name
• twitter.com/delaz
• igor@delka.name
Презентация: delka.github.io/talks/2015/frontendweekend-bem/
Видео доклада: youtube.com/watch?v=kBgHdSOj33A
Презентация, которую вы смотрите, содержит больше слайдов и
153