Форум

Методологія

Інструментарій

Платформа

Спільнота

Історія створення БЕМ

Типова верстка в Яндексі 2005 року

Історія БЕМ почалася в 2005 році. Тоді, з точки зору інтерфейсу, звичайний проект Яндекса був набором статичних HTML-сторінок, які використовувалися як основа для створення шаблонів на XSL.

HTML-сторінки зберігалися в окремій директорії, яка мала таку структуру:

about.html
index.html
…
project.css
project.js
i/
  yandex.png
  • Для кожної сторінки створювався окремий HTML-файл. У верстці використовувалися id і класи.
  • Скрипти зберігалися в одному файлі для всього проекту — project.js. JavaScript використовувався як допоміжний інструмент для пожвавлення сторінки, тому project.js був невеликим.
  • Картинки складалися в окрему директорію. Необхідність підтримки IE 5 і відсутність CSS3 в браузерах, змушувало використовувати картинки для реалізації будь-якого оформлення, навіть для закруглених куточків.
  • Стили, как и скрипты, находились в одном файле — project.css. Для відділення стилів різних частин сторінки використовувалися коментарі з зазначенням початку та кінця:

    /* Content container (begin) */
        #body
        {
            font: 0.8em Arial, sans-serif;
    
            margin: 0.5em 1.95% 0.5em 2%;
        }
    /* Content container (end) */
    
    /* Graphical banner (begin) */
        .banner
        {
            text-align: center;
        }
    
        .banner a
        {
            text-decoration: none;
        }
    /* Graphical banner (end) */
    
    

Зверстані статичні HTML-сторінки нарізалися в XSL-шаблони. Якщо HTML змінювався, всі правки було необхідно переносити вручну в XSL. І навпаки, зміни в шаблонах вимагали правок у HTML для підтримання статичного HTML в актуальному стані).

Зародження основ методології

У 2006 році розпочалася робота над першими великими проектами - Яндекс.Музика і Я. ру. Ці проекти з десятками сторінок виявили основні недоліки поточного підходу до розробки:

  • складно підбирати назви класів;
  • неможливо внести зміни в код однієї сторінки, не зачіпаючи код інший.

Типовий CSS того часу, містить довгий каскад:

/* Albums (begin) */
    .result .albums .info
    {
        padding-right: 8.5em;
    }

    .result .albums .title
    {
        float: left;
        padding-bottom: 0.3em;
    }

    .result .albums .album .listen
    {
        float: left;
        padding: 0.3em 1em 0 1em;
    }

    .result .albums .album .buy
    {
        float: left;
        padding: 0.4em 1em 0 1.6em;
    }

    .result .albums .info i
    {
        font-size: 85%;
    }
/* Albums (end) */

Одночасне використання id і тегів:

/* Картинки на тлі (begin) */
    #foot div
    {
        height: 71px;
        background: transparent url(../i/foot-1.png) 4% 50% no-repeat;
    }

    #foot div div
    {
        background-position: 21%;
        background-image: url(../i/foot-2.png);
    }

    #foot div div div
    {
        background-position: 38%;
        background-image: url(../i/foot-3.png);
    }

    #foot div div div div
    {
        background-position: 54%;
        background-image: url(../i/foot-4.png);
    }

    #foot div div div div div
    {
        background-position: 71%;
        background-image: url(../i/foot-5.png);
    }

    #foot div div div div div div
    {
        background-position: 87%;
        background-image: url(../i/foot-6.png);
    }
/* Картинки на тлі (end) */

Верстка большого проекту була некерованою. Щоб уникнути цього, потрібно було визначити правила роботи з поняттями класу, tag, візуального компонента і не тільки.

Поява блоків

Основний час розробників витрачалося на створення HTML-структури сторінки і написання CSS-стилі для неї. JavaScript сприймався лише як супутня технологія.

Щоб прискорити розробку, потрібно полегшити підтримку HTML і CSS окремих компонентів сторінки. Для цього ми ввели нове поняття – блок.

Блоком називалася частина дизайну сторінки або розкладки зі своїм специфічним і унікальним значенням, визначеним семантично або візуально.

У більшості випадків будь-який компонент на сторінці (складний або простий) розглядався як блок. HTML-контейнер кожного блоку отримував унікальний CSS-клас з тим же ім'ям, що і у блоку.

Класів блоків ми додали префікси (b, c, g), щоб відрізняти їх від внутрішніх класів:

  • b- block Незалежний блок, може використовуватися в будь-якому місці сторінки.
  • с control Контрол (незалежний блок), з яким асоційований JavaScript-об'єкт, що забезпечує його функціональність. Може використовуватися в будь-якому місці сторінки.
  • g- global Глобальне визначення, використовується за необхідності. Кількість зведено до мінімуму.

Крім префіксів використовувалися постфиксы:

  • -nojs no javascript

Стиль застосовується в відсутність JavaScript. Якщо JavaScript включений, то при завантаженні сторінки викликається метод init() в onload, і постфікс видаляється з усіх класів. Так «включався» JavaScript для блоків.

Поява елементів

У HTML-контейнері, що формує блок, деякі вузли одержували чітке ім'я CSS-класу. Це не тільки полегшило створення стилістичних правил, незалежних від імені тега, але й дозволяло присвоювати семантично значущу роль кожного вузла. Такі внутрішні вузли ми назвали елементами блоку, або просто елементами.

Ключова відмінність між блоком і елементом в той момент:

  • елемент не може існувати поза контекстом батьківського блоку;
  • з блоку не можна отримати ні один елемент.

Якщо елемент здатний існувати поза блоку, він стає блоком.

Пізніше стало можливим виймати деякі елементи блоку, зберігаючи при цьому робочий стан самого блоку.

Елементи з великою кількістю коду виділялися коментарями.

/* Head (begin) */
    .b-head { … }

    /* Logo (begin) */
        .b-head .logo { … }
        .b-head .logo a { … }
    /* Logo (end) */

    /* Right side (begin) */
    .b-head .right { … }

        /* Info (begin) */
            .b-head .info { … }
            .b-head .info .exit a { … }
        /* Info (end) */

        /* Search (begin) */
            .b-head .search { … }
            .b-head .search div div, .b-head .search div div i { … }
        /* Search (end) */
    /* Right side (end) */
/* Head (end) */

Уніфікація файлової структури проекту

Розробники інтерфейсів зазвичай підтримують декілька проектів одночасно. Працювати з різними проектами легше, якщо всі вони мають однакову (або дуже схожу) файлову структуру. Тому ми уніфікували структури репозиторіїв різних проектів.

Почали з того, що CSS, JavaScript і картинки стали складати в окремі директорії.

JavaScript застосовувався все частіше, в проект підключалися додаткові компоненти та бібліотеки.

Типова структура верстки проекту 2006 року:

index.html
css/
  yaru.css
  yaru-ie.css
js/
  yaru.js
i/
  yandex.png

Код основний для IE ми писали в загальному CSS-файлі, наприемр, yaru.css.

    /* Common definitions (begin) */
        body
        {
            font: 0.8em Arial, sans-serif;

            padding: 0 0 2em 0;
            background: #fff;
        }

        * html body
        {
            font-size: 80%;
        }

Специфічні правила (тимчасові рішення), що працюють тільки в IE, створювалися в окремому файлі. В ім'я файлу доблялся спеціальний покажчик ie — yaru-ie.css.

    /* Common blocks (begin) */
        /* Artist (begin) */
            .b-artist .i i
            {
                top: expression(7 + (90 - this.parentNode.getElementsByTagName('img')[0].height)/2);
                filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../i/sticker-lt.png', sizingMethod='crop');
            }

Зачатки общепортального фреймворку

При верстці декількох проектів зі схожим дизайном з'являлися загальні блоки.

Портал Яндекса в той час містив більше 100 різних сервісів, виконаних в одному стилі. Для такого обсягу даних «copy/paste» з проекту у проект вже не підходив.

З'явилося загальне сховище повторно використовуваних компонентів, яке називалося загальна бібліотека блоків або просто " Common.

Перші блоки, які увійшли в Common: шапка, підвал і стилі для статичного тексту.

Файли блоків зберігалися на виділеному внутрішньому сервері розробників (common.cloudkill.yandex.ru у наведеному нижче прикладі).

Це було початком роботи нашого общепортального фреймворка. Стилі з нього підключалися в основний проектний файл за допомогою импортов безпосередньо з сервера:

@import url(http://common.cloudkill.yandex.ru/css/global.css);
@import url(http://common.cloudkill.yandex.ru/css/head/common.css);
@import url(http://common.cloudkill.yandex.ru/css/static-text.css);
@import url(http://common.cloudkill.yandex.ru/css/list/hlist.css);
@import url(http://common.cloudkill.yandex.ru/css/list/hlist-middot.css);
@import url(slider.css);

/* Header (begin) */
    /* Service (begin) */
        .b-head .service h1 { … }
        .b-head .service h1, .b-head .service h1 a, .b-head .service h1 b { … }

Виникла проблема: велика кількість импортов уповільнювало завантаження сторінки. Було прийнято рішення прекомпилировать стилі (і пізніше JavaScript-файли) перед викладкою.

Компіляція замінює @import на вміст зовнішніх файлів (це називається inlining) і оптимізує код: наприклад, прибирає непотрібні браузеру прогалини і коментарі.

Наш внутрішній інструмент для оптимізації виріс з простого Perl-скрипта в окремий open-source-проект borschik.

Верстка незалежними блоками

До осені 2007 року правила верстки устоялися. Ми побачили практичну користь від нового підходу, тому було вирішено розповісти про це поза Яндекса.

На ClientSide'07 було зроблено доповідь про верстку незалежними блоками, яка на той момент становила основу наших HTML-сторінок.

У доповіді офіційно вводилося поняття блок:

Блоком будемо називати фрагмент сторінки, який описується своєю розміткою і стилями.

Пізнішій опис.

Блоки поділялися на прості і складові.

Прості блоки не можна вкладати інші блоки, складові — можна.

Це було дуже наївне поділ: ми неодноразово стикалися з тим, що навіть у найпростіші блоки вкладалися інші, і доводилося переробляти верстку. У результаті ми прийшли до протилежного принципом:

Будь блок повинен дозволяти вкладати в нього інший блок, коли це можливо.

Правила незалежності блоків

Сформувалися перші правила незалежності блоку:

  1. Для опису елемента використовується class, а не id.
  2. Кожен блок має префікс.
  3. В таблиці стилів немає класів поза блоків.

Важливим рішенням було відмову від id. Тепер ми могли:

  • відображати на сторінці один і той же блок кілька разів;
  • використовувати на одному DOM-сайті кілька класів (що нам в нагоді надалі).

Правила повної незалежності блоків

З поточною схемою залишався ряд проблем з CSS:

  • CSS міг працювати неправильно, якщо на одній сторінці змішуються стилі з різних джерел.
  • У складних випадках блоки могли шкодити відображення один одного з-за конфлікту імен елементів.
  • Стилі, що спираються на імена тегів, могли охоплювати більше елементів, ніж було задумано.

Тому ми сформулювали правила більш суворої незалежності блоків під назвою абсолютно незалежні блоки (АНБ):

  1. Ніколи не спиратися на елементи - лише на класи. .b-user b -> .b-user .first-letter
  2. Всім класами всередині блоку давати імена, що починаються з імені цього блоку. .b-user .first-letter -> .b-user-first_letter

Ми розуміли, що наявність класу в кожного DOM-сайту суттєво збільшує обсяг HTML-коду. На той момент ми вважали, що це дорого, і застосовували такий підхід у виняткових випадках.

Перші правила іменування — префікси

Так як поширеною проблемою у програмуванні є підбір імен змінних. Ми вирішили задавати імена блоків з допомогою різних префіксів з різною семантикою:

  • b- — звичайні блоки;
  • h- — обгортки для декількох блоків;
  • l- — розкладки;
  • g- — глобальні стилі.

Поява модифікації блоків

Працюючи з блоками, ми зрозуміли, що вони можуть мати різні стани. Наприклад, блок Кнопка може бути представлений в трьох станах: маленька, нормальна і велика.

Замість того, щоб створювати три різних блоку, ми почали робити модифікації одного.

Модифікацію ми визначили як особливий стан блоку або як мітку, що несе певну властивість блоку. Модифікація складалася з імені (наприклад, size) і значення (наприклад, small, normal або big).

Можливі варіанти модифікації:

  1. Блок може змінити свій зовнішній вигляд в залежності від того, де він знаходиться. Це модифікація від контексту.
  2. Можна додати блоку другий клас. Це модифікація постфиксом, вона не залежить від контексту. class="b-block b-block-postfix"

Общепортальный фреймворк — Лего

Навесні 2008 року було поставлено завдання створити брендбук, що описує наш портальний стиль. Вирішили почати роботу з написання HTML/CSS коду.

Проект отримав назву Лего.

Структура репозиторію

На верхньому рівні репозиторій розділений за технологіями:

css/
html/
js/
xml/
xsl/

Директорія кожної технології має свою структуру.

CSS розподіляється на наступні директорії:

  1. block — общепортальные блоки;
  2. util — блоки, которые имеют смысл вне Яндекса, их можно выложить в open source;
  3. service — стили для конкретных сервисов Яндекса. Підключивши їх до сервісу, можна відобразити шапку або підвал.
css/
  block/
    b-dropdown/
      b-dropdown.css
  service/
    auto/
      block/
        b-head-logo-auto.css
      head.css
  util/
    b-hmenu/
      b-hmenu.css

Структура директорії HTML аналогічна CSS:

html/
  block/
    b-dropdown.html
  service/
    auto/
      l-head.html
  util/
    b-hmenu.html

JS знаходиться в зародковому стані і складається в одну директорію:

js/
  check-is-frame.js
  check-session.js
  clean-on-focus.js
  dropdown.js
  event.add.js
  event.del.js

У кожного сервісу є XML-файл, що використовується для побудови шапки:

xml/
  block/
    b-head-tabs-communication.xml
    common-services.ru.xml
    head-messages.ru.xml
  service/
    auto/
      head.xml

XSL блоків знаходиться в одній директорії. Кожному блоку відповідає один файл:

xsl/
  block/
    b-dropdown.xsl
    b-head-line.xsl
    i-common.xsl
    i-locale.xsl
    l-foot.xsl
    l-head.xsl

Лего підключається в проекти з допомогою svn:externals.

При фінальної складанні проекту код бібліотеки повністю включається в проект, що можна порівняти зі статичною линковкой.

Такий підхід дозволяє випускати версії сервісів з різними версіями Лего і переходити на нову версію тоді, коли це зручно команді проекту.

CSS-файли

CSS-файли, подключавшиеся на сторінках, складалися з @importов реалізації блоків.

@import url(../../block/l-head/l-head.css);
@import url(../../block/b-head-logo/b-head-logo.css);
@import url(../../block/b-head-logo/b-head-logo_name.css);
@import url(block/b-head-logo-auto.css);

Ці @importи писалися вручну.

Правила іменування

Іменування файлів ще не устоялося - ми пробуємо різні варіанти.

Общепортальный фреймворк — Лего 1.2 (2008)

Структура репозиторію

В рамках версії Лего 1.2, був проведений рефакторинг, і структура репозиторію проекту змінилася.

common/
  css/
  js/
  xml/
  xsl/
example/
  html/
service/
  auto/
    css/
    xml/

Прибрано поділ на util і block, загальний CSS знаходиться в common/css.

Від ідеї винесення коду в open source на той момент відмовилися і повернулися до неї лише через два роки.

common/
  css/
    b-dropdown/
      arr/
        b-dropdown.arr.css
        b-dropdown.arr.ie.css
        b-dropdown.css
        b-dropdown.ie.css

Все, що знаходилося в опціональному CSS (файлах b-dropdown_arr.css), винесено в директорії (arr/b-dropdown.arr.css). В основному файлі блоку стало менше коду.

Правила іменування

Файли для IE перейменовані: покажчик специфічності файлу для IE був частиною імені файлу, а став суфіксом. Було -ie.css, - стало .ie.css. Розширення файлів тепер можуть складатися з кількох слів.

Для модифікації постфиксом замість дефіса почали використовувати підкреслення. Це дозволило візуально відокремити ім'я блоку від імені модифікатора, що пізніше стало в нагоді при реалізації інструментів, що спрощують роботу з кодом.

Лего 2.0. Поява БЕМ

У березні 2009 року вийшла версія Лего 2.0.

Цією подією закінчується верстка незалежними блоками і починається БЕМ.

БЕМ — абревіатура від Блок-Елемент-Модифікатор. Це три ключові сутності, які ми використовуємо при розробці веб-компонентів.

Що ж принципово змінилося з виходом версії 2.0?

Основна зміна — ми вивели вперед блоки, а не технології. Відтепер блоки первинні, а технології їх реалізації — вторинні.

Реалізацію кожного блоку розмістили в окремій директорії, технології — це файли всередині неї. Також з'явилася документація до блоку — файл .wiki всередині блоку.

Незалежний блок

Може бути використаний в будь-якому місці сторінки.

У XML блок представлений тегом в неймспейсе lego:

<lego:l-head>
<lego:b-head-logo>

HTML-клас блоку відповідає імені цього тега:

<table class="l-head">
<div class="b-head-logo">

CSS-правила пишуться на клас:

.l-head
.b-head-logo

Всі файли (css, js, html, xsl), що належать до блоку, зберігаються в його директорії:

common/
  block/
    b-head-logo/
      b-head-logo.css
      b-head-logo.xsl
      b-head-logo.js
      b-head-logo.wiki

Елемент

Складова частина блоку, яка не може використовуватися у відриві від нього.

У XML елемент представлений в неймспейсе lego без префікса:

<lego:b-head-logo>
    <lego:name/>
</lego:b-head-logo>

Клас в HTML відповідає імені цього тега без префікса.

<div class="b-head-logo">
    <span class="name">Авто</span>
</div>

.b-head-logo .name { ... }

Файли елемента зберігаються в окремій директорії.

common/
  block/
    b-head-logo/
      name/
        b-head-logo.name.css
        b-head-logo.name.png
        b-head-logo.name.wiki

Імена файлів елементів пишуться через точку: b-head-logo.name.css

Модифікатор

Визначає зовнішній вигляд, стан і рідше поведінка блоку.

У XML модифікатор представлений атрибутом в неймспейсе lego:

<lego:b-head-tabs lego:theme="grey">

В HTML використовується додатковий клас:

<div class="b-head-tabs b-head-tabs_grey">

.b-head-tabs_grey { ... }

Файли для модифікатора знаходяться в окремій директорії. Ім'я директорії модифікатора починається з підкреслення:

common/
    block/
        b-head-logo/
            _theme/
                b-head-logo_gray.css
                b-head-logo_gray.png
                b-head-logo_gray.wiki

Декларація використовуваних блоків

Всі Лего-компоненти проекту описуються в XML-файлі.

<lego:page>
    <lego:l-head>
        <lego:b-head-logo>
            <lego:name/>
        </lego:b-head-logo>

        <lego:b-head-tabs type="search-and-content"/>

З нього генеруються CSS-файли.

@import url(../../common/block/global/_type/global_reset.css);
@import url(../../common/block/l-head/l-head.css);
@import url(../../common/block/b-head-logo/b-head-logo.css);
@import url(../../common/block/b-head-logo/name/b-head-logo.name.css);
@import url(../../common/block/b-head-tabs/b-head-tabs.css);
@import url(../../common/block/b-dropdown/b-dropdown.css);
@import url(../../common/block/b-dropdown/text/b-dropdown.text.css);
@import url(../../common/block/b-pseudo-link/b-pseudo-link.css);
@import url(../../common/block/b-dropdown/arrow/b-dropdown.arrow.css);
@import url(../../common/block/b-head-search/b-head-search.css);
@import url(../../common/block/b-search/b-search.css);
@import url(../../common/block/b-search/input/b-search.input.css);
@import url(../../common/block/b-search/sample/b-search.sample.css);
@import url(../../common/block/b-search/precise/b-search.precise.css);
@import url(../../common/block/b-search/button/b-search.button.css);
@import url(../../common/block/b-head-userinfo/b-head-userinfo.css);
@import url(../../common/block/b-user/b-user.css);
@import url(block/b-head-logo/b-head-logo.css);
@import url(block/b-head-search/b-head-search.css);

На прикладі цього файлу видно, що спочатку вказується загальний код, а потім додаються стилі, щоб привести Лего-блоки до дизайну проекту.

З XML-декларації генеруються і JS-файли.

include("../../common/block/i-locale/i-locale.js");
include("../../common/block/b-dropdown/b-dropdown.js");
include("../../common/block/b-search/sample/b-search.sample.js");
include("../../common/block/b-head-userinfo/user/b-head-userinfo.user.js");

А також XSL-файли.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:import href="../../common/block/i-common/i-common.xsl"/>
<xsl:import href="../../common/block/i-items/i-items.xsl"/>
<xsl:import href="../../common/block/l-head/l-head.xsl"/>
<xsl:import href="../../common/block/b-head-logo/b-head-logo.xsl"/>
<xsl:import href="../../common/block/b-head-logo/name/b-head-logo.name.xsl"/>
<xsl:import href="../../common/block/b-head-tabs/b-head-tabs.xsl"/>
<xsl:import href="../../common/block/b-dropdown/b-dropdown.xsl"/>
<xsl:import href="../../common/block/b-pseudo-link/b-pseudo-link.xsl"/>
<xsl:import href="../../common/block/b-head-search/b-head-search.xsl"/>
<xsl:import href="../../common/block/b-search/b-search.xsl"/>
<xsl:import href="../../common/block/b-search/input/b-search.input.xsl"/>
<xsl:import href="../../common/block/b-search/sample/b-search.sample.xsl"/>
<xsl:import href="../../common/block/b-search/precise/b-search.precise.xsl"/>
<xsl:import href="../../common/block/b-search/button/b-search.button.xsl"/>
<xsl:import href="../../common/block/b-head-userinfo/b-head-userinfo.xsl"/>
<xsl:import href="../../common/block/b-user/b-user.xsl"/>
<xsl:import href="../../common/block/b-head-userinfo/service/b-head-userinfo.service.xsl"/>
<xsl:import href="../../common/block/b-head-userinfo/setup/b-head-userinfo.setup.xsl"/>
<xsl:import href="../../common/block/b-head-userinfo/region/b-head-userinfo.region.xsl"/>

</xsl:stylesheet>

Ми перестали писати ці файли руками, почалася генерація коду.

Швидкість селекторів (2009)

При реалізації нової версії Яндекс.Пошти було поставлено завдання зробити її швидко.

Для вирішення завдання ми почали використовувати XSL в браузері (і довантажувати XML, необхідний для відтворення даних на сторінці). Виникла проблема: трансформації відпрацьовувалися швидко, але вставка в DOM отриманого результату відбувалася дуже повільно. При цьому, відключення CSS вирішувало проблему.

З'ясувалося, що уповільнюють роботу селектори CSS, які при великому DOM-дереві і великий таблиці стилів надають істотний вплив на швидкість відтворення браузером сторінки.

Результати дослідження докладно описані в статті.

Рішення проблеми було вже готове — це абсолютно незалежні блоки (АНБ).

Ми перевели всі блоки в Лего на АНБ-позначення і з тих пір створюємо їх так, щоб у кожного DOM-сайту був свій class, на який можна написати стилі. Також ми не використовуємо Tag Rules в CSS.

В класи елементів вноситься ім'я блоку, селектори виходять простими і швидкими.

<div class="b-head-logo">
    <span class="b-head-logo__name">
        Авто
    </span>
</div>

Стабілізація нотації

Поступово ми прийшли до того, що нотація в коді і файлова структура устоялися і вже не змінюються.

  • В іменах файлів роздільник . був замінений на __. Було b-block.elem.css — стало b-block__elem.css. Тепер вони збігаються з CSS-селекторами.

  • Були реалізовані модифікатори у елементів за аналогією з модифікаторами блоків: .b-block__elem_theme_green за аналогією з .b-block_theme_green.

  • В ім'я файлу модифікатора і в його клас внесений тип модифікатора. Було .b-menu__item_current — стало .b-menu__item_state_current. Причина цієї зміни — робота з модифікаторами з JavaScript.

БЕМ і open source (2010)

У 2010 році ми знову повернулися до ідеї open source. Ми створили організацію bem на GitHub.

Бібліотека bem-bl

Ми почали виносити блоки з `Лего " bem-bl, проводячи одночасно з цим рефакторинг.

Паралельно з перенесенням блоків в нову бібліотеку публікували інформацію про них.

Інструменти

Для роботи з файлами за БЕМ-методів нам знадобилися свої інструменти. Почалася реалізація інструментів bem-tools на JavaScript під Node.js.

Возникло новое понятие — уровень переопределения. Так ми стали називати директорії з реалізацією блоків.

Наприклад, у проекті може бути:

  1. Публічна бібліотека блоків з GitHub;
  2. Внутрішня бібліотека lego;
  3. Блоки самого проекту.
bem-bl/
  b-logo/
lego/
  b-logo/
auto/
  blocks/
    b-logo/

На рівні перевизначення можна задати іншу схему іменування папок/файлів, відмінну від нашої. Для цього потрібно вказати новий рівень у конфігурації:

.bem/
level.js

Наприклад, ви можете задати інші роздільник між ім'ям блоку і елемента, або не розкладати все по директоріях, а використовувати плоску структуру файлів.

Шаблонизатор BEMHTML

Після експериментів з різними шаблонізатором, був розроблений шаблонизатор BEMHTML, який дозволяє:

  1. писати шаблони у БЕМ-термінах;
  2. доопределять їх на рівнях перевизначення;
  3. виконувати ці шаблони як на сервері, так і в браузері, оскільки шаблони компілюються в простий і швидкий JavaScript.

Відео з BEMHTML:

Резюме

Появі БЕМ у тому вигляді, що ми маємо зараз, передував довгий період проб і експериментів.

Хочеться звернути вашу увагу, що на всіх етапах свого розвитку це все ж був БЕМ.

Тот БЭМ, что мы используем сейчас, — не единственное верное решение. Ми рекомендуємо використовувати БЕМ у ваших проектах в тому обсязі, в якому він принесе найбільшу користь. Можна пробувати застосовувати його тільки для верстки. Ми самі починали саме з цього. Гнучкість БЕМ-методології дозволяє налаштувати її під свої поточні процеси та організовувати роботу над проектом.

Головне зрозуміти, які плюси БЕМ принесе у ваш проект, вибрати підходящу для вас схему і почати застосовувати у себе!

Якщо у вас виникнуть питання, обов'язково задавайте їх на нашому форумі.

Якщо ви помітили помилку, або хочете доповнити статтю, ви завжди можете або написати нам про це на Гітхабі, або поправити статтю з допомогою prose.io.