Войти с помощью github

Все чаще слышу и читаю про то, что в ближайшем будущем , web выйдет на новый уровень. Использование web-components станет неким стандартом , собственно , на что рассчитывают в W3C. И встает вопрос, что думают по этому поводу ребята из Яндекс ? По сути , он будет уметь и делать все то , что делает сейчас БЭМ , тот же React. Все будет работать только нативными средствами. Что дает не малый прирост в скорости. Как будет жить и существовать БЭМ , после того , как это все станет более имение реальностью?

Привет! Мне нужно будет провести мастер-класс по БЭМ на час. Не презентацию, а именно мастер-класс, когда люди сидят со своими компьютерами и вместе что-то делают. Важно сосредоточиться именно на CSS и немного на декомпозиции и сборке. JavaScript и шаблоны пока не нужны. Кто-нибудь делал подобное? Может быть в ШРИ такое было? Поделитесь, пожалуйста, черновиками, ссылками на репозитории или (ну, вдруг мне повезет) видео. Спасибо!

Добрый день :) Или кому-то ещё утро ;)

Как использовать глобальные переменные less, sass, stylus и т.д. при написании кода?

У меня есть соображение, что нужно объявить блок с ними и потом его просто подключить в проекте где-то вначале, но есть сомнения.

Как это сделать правильней?

Здравствуйте. Начал знакомство с БЭМ-инструментами, до этого использовал только методологию наименования классов. На данный момент хочу использовать бэм-инструменты для верстки однотипных шаблонов. Но у меня возникли проблемы с добавлением новых своих сущностей (а не блоков яндекса из bem-core и bem-components) в common.blocks, внятной документации не нашел. Использую enb-bem + bwmsjon + bemhtml. Также хотелось бы узнать, как отключить минификацию файлов html при сборке. Сейчас весь html склеивается в одну строку, а хотелось бы получать файл, пригодный для дальнейшей интеграции на cms.

Всем привет!

Начал изучать БЭМ CSS. Как я понимаю, блоки должны быть максимально независимы от контекста, в котором они используются., поэтому я при написании блоков выделяю «контекстно-зависимые» стили (margin/padding, переопределения стилей Bootstrap и т.д.) в отдельный блок и навешиваю его вместе с основным блоком на один элемент:

<div class="corp-offer-builder">
  <ul class="pager pull-right corp-offer-builder-ctx__nav">
    …
    <li class="lh-input corp-offer-builder-ctx__page-num">1 из 2</li>
    …
  </ul>
  <div class="btn-group corp-offer-builder-ctx__button_save">
    …
    <ul class="dropdown-menu">…</ul>
  </div>
</div>
.corp-offer-builder-ctx__nav {
  margin: 0;
}

.corp-offer-builder-ctx__page-num {
  padding: 0 10px;
}

.corp-offer-builder-ctx__button_save .dropdown-menu {
  left: auto;
  right: 0;
}

Как я себе представляю, это помогает отделить блок от контекста и использовать его в других местах. Насколько адекватен такой подход и есть ли какие-то другие, возможно, более правильные подходы?

Подскажите как правильно связать несколько блоков например для реализации табов. Например для такой структуры

<div class="block1">
<a href=="#" class="block1__element">Tab 1</a>
<a href=="#" class="block1__element">Tab 2</a>
</div>
<div class="block2">
<div class="block2__elemnt">Tab 1 content</div>
<div class="block2__elemnt">Tab 2 content</div>
</div>

В документации написанно что нужно блокам дать одинаковый id, но что то не соображу как все это грамотно связать

Привет ! Подскажите пожалуйста, в методологии есть возможность создать layout как в Jade , подключать все скрипты в теге head и для других страниц.

Есть такая страничка, заявляющая, что она раскрывает смысл терминов Блок, Элемент, Модификатор. https://ru.bem.info/method/definitions/ Но, во-первых, нет конкретного определения, и, во-вторых, ничего не говорится про технологии, реализации, и другие важные при разработке сборки части.

Надо бы определиться с терминологией и определениями, чтобы можно было двигаться дальше. Подсобите, пожалуйста.

  • БЭМ — акроним Блок-Элемент-Модификатор;
  • Блок — ключевая самодостаточная сущность, описываемая набором реализаций (обычно, набор файлов и папок в папке блока);
  • Элемент — вспомогательная сущность, составная часть блока, описываемая аналогично блоку, которая имеет ровно один родительский блок, и не может использовать вне его контекста;
  • БЭМ-сущность — это определение содержания страницы или сущность в БЭМ-предметной области: блок ИЛИ элемент со всеми его состояниями (модификаторами);
  • БЭМ-предметная область — предметная область, описывающая все возможные варианты БЭМ-сущностей, их свойств, и отношений между ними;
  • Методология БЭМ — это набор паттернов и способ описывать действительность при помощи кода и размышлять о БЭМ-сущностях вне зависимости от того, на каком языке программирования реализуется проект;
  • Модификатор — состояние БЭМ-сущности, описываемое реализациями аналогично БЭМ-сущностям, может иметь строго одно строковое или булевое значение, не может как использоваться отдельно от БЭМ-сущности, так и считаться отедльной БЭМ-сущностью, поскольку является его состоянием (часть целого не может быть целым, если целое состоит не только из этой части);
  • Уровень — набор реализаций БЭМ-сущностей (обычно, набор папок с блоками и их внутренней структурой с элементами и модификаторами);
  • Библиотека — набор уровней;
  • Реализация (в технологии) — функциональная часть БЭМ-сущности, описанная в рамках конкретной технологии файлом или папкой с набором файлов;
  • Технология (tech, technology) — набор процессов для преобразования исходных файлов в целевой продукт (материалов в изделие, результат работы процессов, см. wiki: Технология);
  • БЭМ-технология — технология, применимая к БЭМ-сущностям;
  • Технология сборки — процесс преобразования реализаций блоков, используемый инструментами для сборки (обычно, модуль или набор , stateful?);
  • Технологии борщика — технология, реализуемая js-файлами, используемая инструментом borschik;
  • Цель (сборка) — результат работы технологии сборки;
  • Зависимость — способ включения в сборку сущности или её состояний других сущностей или состояний;
  • Зависимость по БЭМ-технологии — зависимость, используемая в случае сборки определенной БЭМ-технология (верно?);
  • Бандл (сборка) — это набор реализаций сущностей, описанный некоторой специальной реализацией (точкой входа для сборщика с набором сущностей, обычно, в виде реализации технологии bemdecl.js или bemjson.js), и некоторое кол-во собранных целей на выходе, а также способный включать в себя дополнительные уровни;
  • Merged-бандл — частный случай бандла, включающий в себя сборку всех используемых наборов сущностей и их состояний со всех бандлов;
  • Dist-бандл — частный случай бандла, включающий в себя сборку всех доступных БЭМ-сущностей, обычно используется для сборки библиотек;
  • JS-бандл — целевой файл бандла с реализацией JS;
  • CSS-бандл — целевой файл бандла с реализацией CSS (?, противоречит JS-бандлу, где в сборку включаются еще и шаблоны, и стили);
  • JS-бандл (путаница, может mixed-бандл?) — цель специальной технологии, результат которой содержит в себе CSS, JS и шаблоны, поставляемая в виде одного файла технологии JS.

Off-topic. А еще вот такое хочу:

  // возвращаем первое удачно разрешенное
  target('bemdecl', oneOf(
    // либо грузим файл `{level.path}/{bundle.name}/{bundle.name}.bemdecl.js`
    fs.provide('bemdecl.js'),
    // либо пытаемся загрузить bemjson.js и собрать динамически из bemjson.js
    bemjsonToBemdecl(fs.provide('bemjson.js'))
  ));

И снова популярный вопрос про вспомогательные классы, на этот раз его задает ‏@life_maniac.

«Я правильно понимаю, что по БЭМу я не могу добавлять общие вспомогательные классы ко всем блокам? Например, есть класс center, который центрирует содержимое по обеим осям. Хочется иметь его в шапке и еще в паре блоков.»

Да, но нет :)

С одной стороны, БЭМ утверждает: «Не может быть классов вне блоков». С другой стороны, в БЭМ есть понятие миксов — нескольких блоков на одном DOM-узле.

Этот случай — наш.

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

Примером такого блока в bem-core может служить clearfix, а в bem-componentsz-index-group.

Важно помнить, что миксы можно использовать не только в CSS, но и в JavaScript.

Подробнее об этом можно узнать из доклада «Миксы во вселенной БЭМ».

Приветствую, подскажите пожалуйста, куда нужно класть шрифты?

Можем ли мы использовать вместо BEM модификаторов WAI ARIA атрибуты, в случаях, когда нужно отобразить состояние и прочие кейсы на доступность?

Например,

<div aria-disabled="true"></div>

Можем ли мы опираться только на ARIA-атрибуты, если нам нужно написать какую-то логику на задисейбленный элемент?

if (this.attr('aria-disabled')) {}

Коллега аргументирует, что раз мы используем уже методологию, то зачем нам распыляться и использовать атрибуты, если есть модификаторы:

if (this.elem('some-element').mod('disabled')) {}

Говорят, что с БЭМом удобнее и быстрее разрабатывать. Но у нас в проекте всего 10 страниц, когда что-то надо поправить, наш фронтендер всё правит быстро, зачем нам БЭМ? Если кто-то с маленьких проектов может привести пример, как он/она выиграл от БЭМа, будет очень круто.

Телезритель из Воронежа Ваня @voischev задает вопрос на давнюю тему «БЭМ — это не только про CSS», а мы с радостью и отвечаем:

Да, действительно, БЭМ — это не только про CSS.

БЭМ — это про компонентный подход к разработке в целом.

Он предполагает, что каждая полезная сущность (здесь мы называем ее блоком) может быть представлена в одной или сразу нескольких технологиях.

Например, если перед нами логотип, то скорее всего он будет реализован в двух технологиях: шаблоне и стилях.

<a class="logo" href="/">Ваша крутая компания</a>

и

.logo {
    width: 150px;
    height: 100px;
    background: url(logo.png) no-repeat;
}

И шаблон и стили будет удобно положить в одну папку. Так при желании переиспользовать блок мы легко найдем все его части и спокойно перенесем на новое место в отличие от ситуации, когда CSS — это одна «портянка» в папке css/, а JavaScript — в js/, и чтобы перенести какую-то часть куда-то, нужно еще долго копаться в контексте.

Разумеется, встречаются блоки, которым требуется еще и JS для работы. Их реализацию по той же логике, что и выше, мы также кладем в папку с блоком. Выглядеть это может, например, так:

$('.logo').on('click', doSomething);

Конечно, бывают ситуации, когда блок состоит только из CSS (например, clearfix или только JS, как, скажем, блок для работы с куками.

Логика при этом не меняется: это по-прежнему блоки, которые по-прежнему имеют свою папку в файловой системе и аналогично другим блокам попадают в сборку.

Следуя все той же логике, мы реализуем разные технологии блока. Ими могут быть не только традиционные CSS и JS, но и картинки, тесты, документация, примеры использования, исходники и так далее. Со временем блок обрастает нужным «мясом», а мы все также легко можем его декомпозировать и масштабировать без урона для проекта.

В качестве примера можно взглянуть на блок button из библиотеки bem-components.

Когда-то давно БЭМ со своим «компонентным» подходом (тогда он еще так не назывался) нес в массы новые, не всегда понятые идеи. Сегодня ситуация изменилась. Этот же компонентный подход уже не нов и реализован не в одном, а многих продуктах, например, в Polymer или даже в стандарте Web Components.

Рассмотрим на примерах.

«Вы говорите, что блоки должны быть независимыми, но на уровне JavaScript они обязаны общаться друг с другом. Как?»

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

<form class="form" action="/">
    <input class="input" name="email">
    <input class="button" type="submit">
    <div class="popup">Пожалуйста, введите корректный email</div>
</form>
.popup {
    display: none;
}

.popup_visible {
    display: block;
}

Как это могло быть реализовано в стиле old school?

$('.button').on('click', function(e) {
    if (!/\S+@\S+\.\S+/.test($('.input').val())) {
        $('.popup').addClass('popup_visible');
        return false;
    }
});

Всего 6 простых строчек, все работает. Однако, так делать плохо. Почему?

Эти 6 строк кода — отличный пример того, что называют сильной связанностью кода: кнопка «знает» про поле ввода и попап, кроме того, она явно подозревает, что находится внутри формы.

Если в процессе рефакторинга какой-либо из компонентов исчезнет, код сломается. Если появится еще одно поле, код снова сломается. Если вы захотите переиспользовать такую кнопку, вам обязательно придется тянуть за собой все компоненты с такими же классами и гарантировать, что больше нигде на странице они не встречаются.

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

Что можно улучшить?

$('.form').on('submit', function(e) {
    if (/\S+@\S+\.\S+/.test($('.input', this).val())) return true;
    e.preventDefault();
    $('.popup', this).addClass('popup_visible');
});

Что изменилось?

Мы переписали форму так, чтобы за все, что происходит с ней, отвечала она сама. Теперь компоненты внутри ничего не знают о существовании друг друга. А мы можем смело взять кнопку и перенести ее на другой проект, ведь она стала независимой: теперь за ней не потянется знание о какой-то форме, поле ввода и попапе.

Кроме того, мы вынесли все селекторы за рамки контекста формы и теперь можем добавлять сколько угодно новых полей ввода, попапов и кнопок за пределами формы — ничего не сломается.

Есть ли что-то еще, что можно улучшить?

Да. Если мы добавим еще одно поле, придется рефакторить код. Кроме того, чтобы гарантировать перекрытие попапом любых других элементов на странице, нам необходимо положить его в самом конце DOM-дерева, перед закрывающим тегом </body>.

Продолжаем улучшать

Вынесем попап из формы и добавим еще одно поле. Сами поля смиксуем с элементами формы.

Микс — это объединение нескольких блоков на одном DOM-узле.

<form class="form" action="/">
    <input class="input form__login" name="login">
    <input class="input form__email" name="email">
    <input class="button" type="submit">
</form>
<div class="popup form__hint">Пожалуйста, введите корректный email</div>

Теперь наш код выглядит так:

$('.form').on('submit', function(e) {
    if (/\S+@\S+\.\S+/.test($('.form__email', this).val())) return true;
    e.preventDefault();
    $('.form__hint').addClass('popup_visible');
});

Мы исправили предыдущие проблемы, но появилась новая: если на странице окажется несколько форм, как каждая из них найдет свой попап?

Решение, да не одно

В качестве одного из решений мы можем реализовать механизм, который позволит выражать один блок на нескольких DOM-нодах. Схематично он может выглядеть так:

<form class="form" action="/" data-id="1">
    <input class="input form__login" name="login">
    <input class="input form__email" name="email">
    <input class="button" type="submit">
</form>
<div class="popup form form__hint" data-id="1">Пожалуйста, введите корректный email</div>

Мы добавили форме data-атрибут с идентификатором и помимо элемента примиксовали к попапу саму форму с таким же идентификатором. Теперь мы можем в коде сказать, что нам нужен элемент hint именно этого блока form, а не какого-то другого:

$('.form').on('submit', function(e) {
    if (/\S+@\S+\.\S+/.test($('.form__email', this).val())) return true;
    e.preventDefault();
    $('.form__hint').filter('.form[data-id=' + $(this).data('id') + ']').addClass('popup_visible');
});

Следующее решение поможет нам сохранить независимость блоков, но избавиться от необходимости вносить изменения в DOM. Воспользуемся паттерном проектирования Посредник в очень упрощенном виде.

С ним наши компоненты будут знать о существовании посредника, но не будут ничего знать друг о друге. Вся коммуникация будет происходить на основе сообщений, которые компоненты будут публиковать и слушать на посреднике.

Чтобы максимально упростить пример, сделаем таким посредником body. Он всегда присутствует в коде и определенно знает о всех компонентах, которые находятся внутри, + может обеспечить обмен сообщениями.

<body class="page">
    <form class="form" action="/">
        <input class="input form__login" name="login">
        <input class="input form__email" name="email">
        <input class="button" type="submit">
    </form>
    <div class="popup"></div>
</body>
var page = $('.page');

page.on('error', function(e, data) {
    $('.popup')
        .text(data)
        .addClass('popup_visible');
});

$('.form').on('submit', function(e) {
    if (/\S+@\S+\.\S+/.test($('.form__email', this).val())) return true;
    e.preventDefault();
    page.trigger('error', 'Ошибка валидации');
});

Теперь в случае ошибки валидации форма сообщит об этом посреднику — page. Все компоненты, которые должны реагировать на это событие, могут «подписаться» на него через page.on().

В качестве еще одного решения можно воспользоваться паттерном MVC и обеспечить валидацию формы на уровне модели.

Подытожим: методология БЭМ — не только про CSS. Она затрагивает все технологии реализации блока, включая JS, и и помогает писать JavaScript-код, который сохранит независимость ваших блоков, упростит рефакторинг и продлит жизнь проекту.

«Зачем нужен i-bem.js, если можно писать JS для независимых блоков на привычном jQuery

Такой вариант возможен. И более того, i-bem.js написан с использованием jQuery.

Зачем же нам понадобился отдельный блок?

Решая одни и те же задачи на JavaScript в терминах блоков, элементов и модификаторов, мы регулярно делали одни и те же действия. И чтобы автоматизировать процесс и избавиться от копипаста, а также предоставить удобные хелперы пользователям, мы написали i-bem.js.

Если у вас остались вопросы, смело задавайте их в комментариях. Мы обязательно ответим!

По мотивам обсуждения в твиттере с подачи @delaz, решили написать пост и собрать еще вопросов и тем для разъяснения, которые в будущем планируем добавить в раздел про методологию.

Что у нас получилось?

  1. БЭМ — это не про префиксы.
  2. БЭМ — это не про длинные названия классов.
  3. Нельзя использовать элементы элементов в нейминге.
  4. Миксы.
  5. БЭМ не запрещает каскад (но и не приветствует).
  6. Как понять, когда делать блок, а когда — элемент.

Пойдем по порядку, а вы задавайте вопросы или дополняйте список в комментариях. Ответы будем выносить в пост.

«БЭМ — это длинные имена классов. b-button — это длинно!»

Отвечаем: БЭМ не навязывает префиксы. Чтобы писать хорошо поддерживаемый и реиспользуемый код, префиксы совершенно не нужны. Исторически они появились в переходный период для того, чтобы отличать новый код, написаный по БЭМ, от старого. Со временем мы от них отказались. Если посмотреть в код, можно увидеть, что префиксов там нет.

«А как же префикс js- или i- для блоков без визуального представления?»

Когда-то можно было сверстать сайт практически без JS-кода. Сейчас большая часть блоков имеет JS-представление. Глядя на текущую ситуацию мы поняли, что нет нужды как-то отличать технологии реализации блока на уровне нейминга. Посмотрите, к примеру, на Web Components. Объективно необходимости в префиксах нет, но каждый волен выбирать, что ему, проекту или команде удобнее и/или привычнее.

«Префиксы — ладно. А просто длинные названия блоков?»

В этом и похожих случаях вы можете использовать классы типа btn вместо button. Это никак не помешает вам разрабатывать по БЭМ. Все как с названием переменных в JS: context, ctx или c. Но помните, вам, вашим коллегам и тем, кто будет разрабатывать и поддерживать проект после вас это предстоит читать, понимать и с этим работать ;)

Остается вопрос про неймспейсы — мы пишем имя блока перед именем элементов (button__icon) и модификаторов (button_active).

Если декомпозировать «проблему», можно выделить 2 потенциальных минуса:

  • Результирующий код, который приходится гонять по сети, весит больше. Тут на помощь приходит gzip, который отлично жмет повторяющиеся последовательности и сводит минус на нет.
  • Приходится больше кнопок нажимать на клавиатуре. Здесь помогают автокомплит в редакторе и инструментарий, который автоматически добавляет префиксы (CSS-препроцессоры и шаблонизаторы). Когда вы видите эти два минуса и больше ничего кроме них, мы предлагаем подумать и выбрать, что важнее — время, необходимое на нажатие клавиш, или время, затраченное на обдумывание архитектуры. Во втором случае БЭМ как раз очень сильно помогает. А первое легко автоматизировать не в урон проекту.

И тогда, благодаря неймспейсам, будет решено следующее:

  1. Исчезнет опасность случайно «задеть» внутреннее устройство блока. Мы получим аналог скоупа в JS, но для CSS. Для этого в Web Components придумали Shadow DOM, но в действительности простого добавления имени блока достаточно, чтобы получить тот же результат без лишних телодвижений.
  2. С первого взгляда на любой класс, хоть в CSS, хоть в HTML, хоть в любой другой технологии реализации блока, мы тут же поймем, к какому блоку он относится и какую задачу решает. Сравните: active (на что повлияет этот класс?) VS. input_active или item VS. nav__item.

Да. И к тому же не по БЭМу :)

Неймспейсом служит только имя блока. А отражать вложенность в именах элементов не нужно. Это не только длинно, но еще и не позволит при повторном использовании блока в другой ситуации (или просто при рефакторинге) легко вынуть один элемент из другого. Плоская структура касается не только нейминга, но и расположения кода на файловой системе:

nav/
    __item/
        nav__item.css
    __link/
        nav__link.css

Для выражения вложенности вполне достаточно DOM-дерева:

<ul class="nav">
    <li class="nav__item">
        <a class="nav__link"></a>
    </li>
</ul>

Тут нам на помощь приходят миксы — возможность смешать на одном DOM-узле несколько блоков (или элементов/модификаторов) одновременно.

Предыдущий пример вполне может выглядеть так:

<ul class="nav">
    <li class="nav__item">
        <a class="link nav__link"></a>
    </li>
</ul>

При этом все общее, что есть у всех ссылок на проекте, будет описано в блоке link, а особенности, присущие только ссылке внутри nav — для nav__link.

  1. Это несемантично. А если там в будущем окажется не ссылка вовсе?
  2. Во-вторых, это влечет за собой дополнительные сложности, ведь каскад затронет и вложенные сущности. Например, если в будущем вы захотите усложнить архитектуру или добавить выпадающее меню.
  3. Наконец, структура может поменяться и nav__item совсем исчезнуть.

    «Получается, что в каскадных таблицах стилей нельзя использовать каскад?»

Можно. Но нужно понимать, какие последствия это влечет. Например, каскад уместен, чтобы менять элементы в зависимости от состояния блока (.nav_hover .nav__link { text-decoration: underline; }) или, скажем, темы (.nav_theme_islands .nav__item { line-height: 1.5; }).

Но в случае использования каскада вы рискуете повысить связанность кода и сделать его реиспользование невозможным, что в будущем может привести к ситуации, когда переписать проще, чем исправить.

«Как в принципе отличать, где блок, а где элемент?»

Если хочется переиспользовать кусок кода вне контекста родителя — это точно блок. Если кусок кода не имеет смысла без родителя — это скорее всего элемент. Аналогией служит Shadow DOM в Web Components.

Исключением может быть ситуация, когда у такого элемента оказывается слишком богатый внутренний мир и возникает желание сделать его собственные элементы. Тогда это можно представить как служебный «приватный» блок.

Что скажете? Наши ответы помогут вам разобраться в ваших ситуациях или же нам стоит подумать над чем-то еще? Будет очень здорово получить от вас вопросы или же примеры, которые мы сможем объяснить. А потом вынести всю эту полезную информацию в раздел сайта.

Очень ждем ваших комментариев!

В данный момент делаю БЕМ верстку для простого блога. Заказчик хочет что бы ссылки были по умолчанию зеленого цвете, без указания класса. Но написать a{color: green;} противоречит БЭМу. Как быть?

Добрый вечер. Хочу попробовать внедрение методологии БЭМ в документировании принципов сборки приложения на основе общих высокоуровневых блоков (заголовок приложения, навигация, система уведомлений, справочники, компоненты и т.д.).

Что ожидаю получить:

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

Что потребуется:

  • Терминология, принципы именования и размещения на файловой системе - заимствуются у БЭМ
  • Выбор технологий для описаний, макетов, примеров
  • Инструменты и технологии сборки
  • Технология публикации артефактов и документации (сайт)
  • Упоротость и удача
  • Преодоление множества "подводных граблей" на пути к мечте

Данный пост можно рассматривать:

  • попытку определить и упорядочить цели и задачи
  • сбособ получить критику, замечания и напутствия от сообщества

Зачем мне писать <div class=”block block_mod”>, разве я не могу всё описать в .block_mod? При этом все модификаторы разложить в разные файлы и подключать только нужный. А благодаря препроцессорам можно подмешивать код блока к каждому модификатору и так избежать копипаста.

Я использую БЭМ на уровне написания классов. т.е. использую только сам принцип плоских стилей и все. Я выбрал такое пространство имен: blok-neme , block-nema--elem, block-name--elem__mod. У меня на страничках часто встречается текст оранжевого цвета, раньше я добавлял класс .orange нужному элементу и все. Можно ли также поступать с БЕМ версткой?

Добрый день! Начал изучать БЭМ и возникли вопросы. Есть такая разметка

<div class='b-container__part1'> элемент места для блока
    <div class='b-slider'> блок
        <div class='b-slider__text'> элемент места для блока text
            <div class='b-text'> блок с текстом
    <div class='b-slider__img'> элемент места для блока img
        <div class='b-img'> блок с изображением

Нужно задать размеры и расположение блоков текста и изображения. Эти параметры нужно применять к элементу места или непосредственно к блоку?

Ещё возник вопрос, что делать в следующей ситуации. Есть например блок tile

.tile {
  text-align: center;
}

и есть миксин getting-started

.getting-started {
  text-align: left;
}

Так исторически сложилось, что миксин подключается раньше основных стилей, и выравнивание текста, соответственно, не то, которое мы бы хотели.

Сейчас мы делаем хак для getting-started:

.getting-started.tile {
  text-align: left;
}

Но это слегка попахивает. Как разрулить эту ситуацию покрасивее?

Как правильно реализовать наследование с BEM?

Предположим, у меня есть блок list

.list {
  font-size: 14px
}

и есть блок teaser, где этот list используется с размером шрифта 18px.

Чисто по логике, я бы сделал наверное как-то так:

.teaser__list {
  font-size: 18px
}

Но мои коллеги категорически не приемлют такого решения и утверждают, что мне нужно сделать модификатор от list, увеличивающий размер шрифта:

.list__text-size_18 {
  font-size: 18px
}

Так как правильно?

Привет. Как я понимаю BEViS это одна из реализаций идеи независимых блоков. В описания BEViS он часто сравнивается с БЭМ, и часто встречаются негативные отзывы о БЭМ (мол миксы это не естественно и т.д.). Какое выше мнение o методологии BEViS? Какое выше отношение к их негативным отзывам о БЭМ, считаете ли вы их аргументированными?

У меня есть блоки

.square-box
.shadow
.flip-box
.product-card

Нужно сделать карточку продукта квадратной и переворачивающийся, вышел такой haml

.product-card <-- начало блока
  .square-box
    .square-box__content
      .flip-box
        .flip-box__wrapper
          .flip-box__front
            .shadow.shadow--1
              .product-card__title ... <-- И только здесь начались его элементы
              .product-card__image ...

          .flip-box__back
            .shadow.shadow--1 Back content

Получается, что product-card оборачивает пару блоков, которые оборачивают элементы product-card... вписывается ли это в методологию? На текущий момент есть идея вынести стороны карточки продукта в разные блоки product-front-side и product-back-side, но все равно интересно получить ответ на вопрос.

Добрый день, весёлая минутка! Здравствуйте.

На новой версии проекта решили использовать БЭМ для работы с шаблонами страниц. Создали репозиторий на основе project-stub. Одновременно хотим вести несколько подпроектов в одном репозитории. Вроде бы, это возможно при использовании разных уровней переопределения, как мне показалось. Столкнулись со следующей проблемой:

  • Создаём свой уровень переопределения для страниц:

$ bem create level site.bundles -l .bem/levels/bundles.js

  • Получаем папку site.bundles очень похожую на "родную" desktop.bundles: в .bem/levels.js всё идентично "натуральному".
  • Создаём блок main в site.bundles:

$ bem create -b main -l site.bundles -T bemjson.js

  • В site.bundles/main наблюдаем main.bemjson.js .
  • Запускаем сборку:

$ bem make

  • Наблюдаем стэктрейс (/opt/markup - расположение нашего репозитория):

TypeError: First argument needs to be a number, array or string.
at new Buffer (buffer.js:188:15)
at Writer.self.write (/opt/markup/node_modules/bem/node_modules/q-io/writer.js:47:23)
at /opt/markup/node_modules/bem/node_modules/q-io/fs-common.js:84:34
at _fulfilled (/opt/markup/node_modules/bem/node_modules/q/q.js:798:54)
at self.promiseDispatch.done (/opt/markup/node_modules/bem/node_modules/q/q.js:827:30)
at Promise.promise.promiseDispatch (/opt/markup/node_modules/bem/node_modules/q/q.js:760:13)
at /opt/markup/node_modules/bem/node_modules/q/q.js:526:49
at flush (/opt/markup/node_modules/bem/node_modules/q/q.js:108:17)
at process._tickCallback (node.js:415:13)

Что-то явно упускаю в настройке, но пока не понимаю отчётливо, что именно. Возможно, новый уровень переопределения надо куда-то также задекларировать? Но куда?

Требуется совет гуру.

Привет! Начал изучать методологию на тестовом проекте. Для начала решил использовать только html/css в терминах БЭМ, чтобы немного освоиться. И сразу возникла проблема с выделением сущностей. Допустим есть такая разметка:

<body class="b-body">
    <canvas class="b-background"></canvas>
    <section class="b-inform-box b-inform-box_rounded">
        <div class="b-inform-box__header">
            <div class="b-background"></div>
        </div>
        <div class="b-inform-box__main"></div>
    </section>
</body>

Если словесно описать, вот что должно получиться:

  • canvas.b-background - это размытая картинка, которая растянута на весь экран, расположена ниже всех элементов по z-index;
  • b-inform-box - это просто блок размещенный строго по середине экрана;
  • div.b-background - это та же картинка, что и рисуется на canvas, но не размытая и растянута на ширину/высоту родителя.;

Визуально это выглядит так: https://www.dropbox.com/s/u0gay77vg5u7hsh/bg.jpg?dl=0

Исходя из описания видно, что, в принципе, блок canvas.b-background и div.b-background это одно и тоже. По крайней мере css описание одно и тоже.:

.b-background {
    position: absolute;
    z-index: 0;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

Но при дальнейшем подключении JS, встает вопрос, т.к. способы установки изображений на эти блоки разные. На canvas я рисую размытое изображение, а на div я устанавливаю css свойство background-image. Т.е., грубо говоря, различие блоков только в JS методе draw().

Нужно как-то эти два блока разделить, например на: b-page-bg и b-inform-box-bg? Или использовать один b-background, но как тогда организовать различный для обоих блоков js код?

Многовато написал, но хотел подробнее все расписать. Надеюсь что все понятно, и вы мне поможете разобраться. Хочу освоить БЭМ ^^

Ресеты — общепринятая практика. Многие фреймворки сначала приводят все к общему виду, а потом накладывают свои классы. А БЭМ не рекомендует общие ресеты. Это так? Почему? И что предлагается вместо этого?

Что делать, если у блока очень глубоковложенная структура? block__elem1__elem2__elem3 выглядит устрашающе.

Я хочу использовать общее название модификатора, обозначающего роль блока. Например, есть некий блок login-form, и в нём два одинаковых блока input (с ролями login и passworrd), и два блока одинаковых button (с ролями submit и register). Скрипт блока login-form будет искать внутри каждого login-form блоки input и button, и в зависимости от их роли описывать поведение.

Как назвать такой модификатор?

-input_type_login Точно не то, предполагает серьёзные различия блоков, а мой модификатор будет навешиваться даже на что-то динамически генерируемое. Например, подгрузятся несколько постов, и чтобы различать их в скрипте, будут они post_type_1245, post_type_1246.

-input_id_login Лучше, но тоже не подходит, идентификатор предполагает всё же нечто уникальное, а блоков логина может быть несколько (при условии, что они будут в разных login-form)

-input_role_login Тоже как-то странно будет видеть post_role_1247.

Может всё же есть подходящее слово? Ещё я не уверен, делать ли это модификатором, или, например, кастомным аттрибутом, но кажется, что модификатором всё же лучше.

Есть ли сравнение преимуществ использования BEM в CSS относительно AMCSS, OOCSS, SUITCSS или SMACSS? В чем принципиальные различия?

Что отвечать на вопрос "чем вы лучше вот этих парней"? — ответ "мы были первые" слабо убеждает людей использовать БЭМ. Большинство идут за "хипстерскими" и более свежими подходами, нежели за проверенным временем.