БЭМ, следующий уровень

По мотивам статьи на Хабре и флейма вокруг нее. Статья написана для тех кто хочет попробовать БЭМ, но не знает с какой стороны за него взяться. При первом взгляде на БЭМ, он кажется логичным и невероятно удобным. Но при попытке реализовать пользователь сталкивается с препятствиями, которые нивелируют все достоинства. Я не знаю как и почему создавалась эта методология, меня это не парит, если использовать правильно, то это прикольно, я же не задумываюсь для чего когда-то строили автомобиль или самолет, зато сейчас им пользоваться удобно, это же просто удобный инструмент. Знаю только, что при создании, никто не собирался стили и классы писать одним полотном.

Я попытаюсь рассмотреть один из многих вариантов применения методологии БЭМ на практике, который не только соответствует духу, но и рекомендациям создателей.

На мой вгляд главная проблема БЭМ не в сложных и длинных именах, или отсутствии каскада (что кстати не всегда правда). А в непонимании многих зачем им это нужно. Писать и без того сложно читаемый 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 и копировать между проектами всем скопом. А если еще вступить в предварительный сговор с дизайнером и бекендом, жизнь вообще представляется в розовом цвете.

Минусы:
  1. Вся информация хранится в одном объекте, едином для всей страницы, поэтому блоки не совсем независимые. Нужно внимательно следить за ключами. И лучше сразу все тщательно документировать;
  2. Конечно, очень мешает, что мелкие повторяющиеся блоки (кнопки, например), которых много на странице, но в разном окружении, придется импортировать очень аккуратно. Может быть экран использовать...
  3. Все зависимости пишем ручками. Конечно можно и скриптик для этого написать;
  4. Сейчас модификаторы не влияют на HTML разметку и JS.


Все проблемы решают bem-bl + bem-tools. О том как пользоваться этими двумя инструментами для рядового проекта, расскажем в следующей статье.

UPD: Товарищи минусующие, я понимаю что мои писательские способности далеки от совершенства, и любую конструктивную критику приветствую. Вот только не забывайте ее оставлять в комментариях к статье. Спасибо :)
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 8

    0
    А что обозначает БЕМ?
      +2
      Спасибо, уже исправил.
        –1
        А что обозначает БЭМ?
          +2
          А текст статьи прочитать, по ссылочкам потыкать, не? Религия не позволяет?
            +1
            Как раз к этому я и вел мысль. Конечно я могу потыкать по ссылочкам, почитать «что обозначает БЭМ». Я даже могу не использовать ссылки статьи и поискать в гугле! Но неужели сложно быть более лояльным к читателю и сделать небольшое вступление? Лично я текст статьи почитал, тщетно пытаясь найти в ней хоть какое то разъяснение о чем идет вообще речь. Почитал ровно до 4 абзаца, когда стало понятно что описываться будет не технология (методология, или что бы там ни было), указанная в заголовке, а просто некоторая ее реализация. Т.е. чтобы понять о чем вообще вы пишете, я уже должен знать «что обозначает БЭМ». Хорошо что это определение можно найти в статье, которая указана «по мотивам», но текст предложения не содержит такого указания, типа: «немного о БЭМ вы можете почитать тут». Проще говоря — для полноты статьи не хватает некоего реферата.
              0
              Одно предложение — шестой абзац. Читайте внимательно. Профильные статьи очень редко начинаются с рефратов или ссылок. На секунду оторвитесь от тролинга и подумайте что статья может быть написанно не для всех, а для тех кто понимает что это.
              И первый автор комментария имел ввиду именно ошибку в написании, или мне вам показать личную переписку?
                0
                Вот тебе и «любую конструктивную критику приветствую»! Разве это троллинг? Всего лишь предложение как улучшить конкретную статью, не обращая внимание на то, что «Профильные статьи очень редко начинаются с рефратов или ссылок». Изложенная выше причина заставила конкретно меня отказаться от прочтения данной статьи, хотя наверняка она может быть кому-то полезной. И поэтому я максимально подробно постарался донести что в статье именно меня, как конкретного читателя, не устроило. Большинство же толковых профильных статей, опубликованных на хабре, имеют либо подобный реферат, либо описание порога вхождения. Для вашей статьи надо знать не только что такое БЭМ и, соответственно, CSS но и node.js Если бы я узнал об этом в первых абзацах, я бы даже не писал бы эти комментарии.
                  0
                  Мдя… вы точно читали статью? В первом абзаце описано для кого эта статья и почему написана, в четвертом о технологиях в шестом уже уточняется, что конкретно будет рассматриваться. С учетом что в абзацах по два предложения то это очень-очень в начале, не понимаю, что нужно было списком в начале задать: «Для прочтения статьи знать это ...» и пункты расписать? Все таки стоит уточнить что такое конструктивная критика.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое