По мотивам статьи на Хабре и флейма вокруг нее. Статья написана для тех кто хочет попробовать БЭМ, но не знает с какой стороны за него взяться. При первом взгляде на БЭМ, он кажется логичным и невероятно удобным. Но при попытке реализовать пользователь сталкивается с препятствиями, которые нивелируют все достоинства. Я не знаю как и почему создавалась эта методология, меня это не парит, если использовать правильно, то это прикольно, я же не задумываюсь для чего когда-то строили автомобиль или самолет, зато сейчас им пользоваться удобно, это же просто удобный инструмент. Знаю только, что при создании, никто не собирался стили и классы писать одним полотном.
Я попытаюсь рассмотреть один из многих вариантов применения методологии БЭМ на практике, который не только соответствует духу, но и рекомендациям создателей.
На мой вгляд главная проблема БЭМ не в сложных и длинных именах, или отсутствии каскада (что кстати не всегда правда). А в непонимании многих зачем им это нужно. Писать и без того сложно читаемый HTML код руками, добавлять монструозные имена класса тем самым еще более нагромождая код, ой как не хотелось. А уж CSS длинной более 3000 строк вообще вызывал рвотные позывы. И только после знакомства с БЭМ инфраструктурой я понял все прелести данного подхода. Здесь мы рассмотрим сам подход оставив в стороне инструменты разработанные создателями БЭМ, чтобы сосредоточиться на самой реализации и глубже понять весь процесс.
Для этого я использовал Node.js, фреймворк Express, установив его со стандартным шаблонизатором Jade и CSS препроцессором Stylus.
Сам проект лежит тут: github.com/jchouse/bem-school_type_middle
Инструкция по запуску в readme.
Если внимательно читать статьи о БЭМ, можно увидеть что БЭМ это не только длинные классы, но и определенную файловую структуру. Перво-наперво создадим папку где будем хранить БЭМ блоки.
Я думаю, не стоит описывать весь путь создания этого проекта поэтапно, это можно посмотреть по коммитам. Я лишь обращу ваше внимание на основные концепции которыми я руководствовался.
Подготовим простой объект с информацией (конечно он может собираться из базы данных, или быть захардкоженным):
routes/index.js
ВНИМАНИЕ: информация захардкожена, при изменении, нужно перезапустить сервер. Для чистой верстки можно писать текст в Jade блока, а клиенту отдавать сгенерированный HTML.
Минимум кода в шаблоне страницы, лишь самое необходимое.
views/index.jade
Весь код описания блока по возможности помещать внутри самого блока.
Это обёртка страницы которая остается неизменной (заголовок, футер и т.д.):
blocks/page/page.jade
Основное меню:
blocks/main-menu/main-menu.jade
В общий CSS мы записываем только импорты, сами стили лежат в соответствующей папке блока.
Общие стили, служит для импорта всех блоков:
public/stylesheets/style.styl
Стили одного блока, здесь есть описание самого блока, а также импорты стилей модификаторов и элементов.
blocks/main-menu/main-menu.styl
Стили одного блока:
Сложное имя класса указывает в первую очередь на место где можно найти этот стиль, при чем не пользуясь поиском по документу или скроля весь документ.


Чтобы все это работало я применил внутренние элементы импорта, прописав все зависимости руками.
Префиксы использовать не обязательно. Но можно для блоков, которые не имеют визуального представления или для вспомогательных блоков. Например, блок с переменными или блок чистки потока от флоатов. Сами по себе префиксы родились для того, чтобы с первого взгляда отличить блок от элемента блока, в таких реализациях как XSL. Так как мы прописываем имя стиля целиком — надобность в них отпадает.
И да! Такой подход дает настоящую реюзабельность, копируешь и вставляешь в новый проект папку блока и, вуаля, он уже в твоем проекте. Причем блоки используемые во всех документах можно вынести в blocks-common и копировать между проектами всем скопом. А если еще вступить в предварительный сговор с дизайнером и бекендом, жизнь вообще представляется в розовом цвете.
Минусы:
Все проблемы решают bem-bl + bem-tools. О том как пользоваться этими двумя инструментами для рядового проекта, расскажем в следующей статье.
UPD: Товарищи минусующие, я понимаю что мои писательские способности далеки от совершенства, и любую конструктивную критику приветствую. Вот только не забывайте ее оставлять в комментариях к статье. Спасибо :)
Я попытаюсь рассмотреть один из многих вариантов применения методологии БЭМ на практике, который не только соответствует духу, но и рекомендациям создателей.
На мой вгляд главная проблема БЭМ не в сложных и длинных именах, или отсутствии каскада (что кстати не всегда правда). А в непонимании многих зачем им это нужно. Писать и без того сложно читаемый HTML код руками, добавлять монструозные имена класса тем самым еще более нагромождая код, ой как не хотелось. А уж CSS длинной более 3000 строк вообще вызывал рвотные позывы. И только после знакомства с БЭМ инфраструктурой я понял все прелести данного подхода. Здесь мы рассмотрим сам подход оставив в стороне инструменты разработанные создателями БЭМ, чтобы сосредоточиться на самой реализации и глубже понять весь процесс.
Для этого я использовал Node.js, фреймворк Express, установив его со стандартным шаблонизатором Jade и CSS препроцессором Stylus.
Сам проект лежит тут: github.com/jchouse/bem-school_type_middle
Инструкция по запуску в readme.
Если внимательно читать статьи о БЭМ, можно увидеть что БЭМ это не только длинные классы, но и определенную файловую структуру. Перво-наперво создадим папку где будем хранить БЭМ блоки.
Я думаю, не стоит описывать весь путь создания этого проекта поэтапно, это можно посмотреть по коммитам. Я лишь обращу ваше внимание на основные концепции которыми я руководствовался.
Подготовим простой объект с информацией (конечно он может собираться из базы данных, или быть захардкоженным):
routes/index.js
res.render('index',
{
title: 'BEM средняя школа',
menu: [
{
url: '#home',
content: 'Главная'
},
{
url: '#port',
content: 'Портфолио'
},
...........
ВНИМАНИЕ: информация захардкожена, при изменении, нужно перезапустить сервер. Для чистой верстки можно писать текст в Jade блока, а клиенту отдавать сгенерированный HTML.
Минимум кода в шаблоне страницы, лишь самое необходимое.
views/index.jade
extends ../blocks/page/page
block content
include ../blocks/content/content
Весь код описания блока по возможности помещать внутри самого блока.
Это обёртка страницы которая остается неизменной (заголовок, футер и т.д.):
blocks/page/page.jade
doctype 5
html
include ../head/head
body.page
div.page__wrapper
include ../main-menu/main-menu
block content
include ../footer/footer
Основное меню:
blocks/main-menu/main-menu.jade
ul.main-menu.main-menu_type_horiz
each item in menu
li.main-menu__item
a(href='#{item.url}')= item.content
В общий CSS мы записываем только импорты, сами стили лежат в соответствующей папке блока.
Общие стили, служит для импорта всех блоков:
public/stylesheets/style.styl
@import '../../blocks/page/page'
@import '../../blocks/main-menu/main-menu'
@import '../../blocks/footer/footer'
Стили одного блока, здесь есть описание самого блока, а также импорты стилей модификаторов и элементов.
blocks/main-menu/main-menu.styl
.main-menu
margin: 0;
padding: 0;
text-align: center;
list-style-type: none;
// Модификаторы
@import '_type/main-menu_type_horiz'
// Блоки
@import '__item/main-menu__item'
Стили одного блока:
Сложное имя класса указывает в первую очередь на место где можно найти этот стиль, при чем не пользуясь поиском по документу или скроля весь документ.


Чтобы все это работало я применил внутренние элементы импорта, прописав все зависимости руками.
Префиксы использовать не обязательно. Но можно для блоков, которые не имеют визуального представления или для вспомогательных блоков. Например, блок с переменными или блок чистки потока от флоатов. Сами по себе префиксы родились для того, чтобы с первого взгляда отличить блок от элемента блока, в таких реализациях как XSL. Так как мы прописываем имя стиля целиком — надобность в них отпадает.
И да! Такой подход дает настоящую реюзабельность, копируешь и вставляешь в новый проект папку блока и, вуаля, он уже в твоем проекте. Причем блоки используемые во всех документах можно вынести в blocks-common и копировать между проектами всем скопом. А если еще вступить в предварительный сговор с дизайнером и бекендом, жизнь вообще представляется в розовом цвете.
Минусы:
- Вся информация хранится в одном объекте, едином для всей страницы, поэтому блоки не совсем независимые. Нужно внимательно следить за ключами. И лучше сразу все тщательно документировать;
- Конечно, очень мешает, что мелкие повторяющиеся блоки (кнопки, например), которых много на странице, но в разном окружении, придется импортировать очень аккуратно. Может быть экран использовать...
- Все зависимости пишем ручками. Конечно можно и скриптик для этого написать;
- Сейчас модификаторы не влияют на HTML разметку и JS.
Все проблемы решают bem-bl + bem-tools. О том как пользоваться этими двумя инструментами для рядового проекта, расскажем в следующей статье.
UPD: Товарищи минусующие, я понимаю что мои писательские способности далеки от совершенства, и любую конструктивную критику приветствую. Вот только не забывайте ее оставлять в комментариях к статье. Спасибо :)