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

Например, на проекте есть несколько разделов. В каждом разделе есть общие блоки (кнопки, инпуты и т.д.). Но так как для каждого раздела собирается свой бандл, то получается разные файлы стилей/скриптов с одинаковыми кусками кода (кнопки, инпуты и т.д.). И браузер постоянно грузит одно и то же. Как можно сделать какой-нибудь общий бандл (типа common), в котором эти кнопки, инпуты и т.д., а уже для каждого раздела свои бандлы из блоков, которые присутствуют только в этом разделе?

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

Получаю следующую картину: после полной загрузки страницы и окончания инициализации js созданный динамически select не работает вообще. В обоих случаях bemjson один и тот же. В динамически созданном select'е в button'е отсутствует текстовый элемент, видимо, из-за этого весь блок select превращается в тыкву нерабочий компонент. Может быть, я что-то упустила, но никак не могу понять, что именно.

Код (выкачивала project-stub, изменения внесены минимальные): https://github.com/kvmamich/bem-dynamicselect Скриншот: https://raw.githubusercontent.com/kvmamich/bem-dynamicselect/master/screenshot.png

Телезритель из Воронежа Ваня @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.

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

толкнулись с проблемой распределения картинок по блокам Решили что наилучшим способом будет папка /block ../i ....block__element.jpg

Есть ли технология под сборку картинок? Я про bem-tools

Может быть будем вырезать такие строчки из комментов при выводе на форуме?

Reply to this email directly or view it on GitHub https://github.com/bem/bem-forum-content-ru/issues/129#issuecomment-65544808.

Пример тут: http://ru.bem.info/forum/issues/129/

По просьбе в твиттере от @life_maniac.

Те, кто используют наши шаблонизаторы BEMHTML или BH для верстки статики, часто спрашивают, как отключить минимизацию получаемого HTML.

Но не многие знают, что на самом деле никакой минимизации не происходит.

Почему? Потому что шаблонизаторы изначально генерируют из BEMJSON оптимальный для продакшена HTML.

Если вам необходимо получать красиво отформатированный HTML, подойдет любой pritty-print, например, js-beautify.

Его можно звать через CLI (js-beautify --html) либо встроить прямо в технологию сборки через JS API.

Приведу примеры такой технологии для bem-tools и ENB (технология написана исходя из предположения, что вы используете project-stub).

bem-tools

var BEM = require('bem'),
    Q = BEM.require('q'),
    environ = require('bem-environ'),
    join = require('path').join,
    BEMBL_TECHS = environ.getLibPath('bem-bl', 'blocks-common/i-bem/bem/techs'),

    beautify = require('js-beautify').html;

exports.baseTechPath = join(BEMBL_TECHS, 'html.js');

exports.techMixin = {
    getCreateResult: function(path, suffix, vars) {
        // не вызывать js-beautify в production-режиме
        if (process.env.YENV === 'production') return this.__base.apply(this, arguments);

        return this.__base.apply(this, arguments)
            .then(function(html) {
                return beautify(html, { /* см. доступные опции https://www.npmjs.com/package/js-beautify#options */ });
            });
    }
};

ENB

Для ENB приводить полный листинг не буду. Все сводится к полному копипасту html-from-bemjson.js с добавлением вызова бьютифаера на 40 строке:

var html = bemhtml.BEMHTML.apply(json);

return process.env.YENV === 'production' ? html : require('js-beautify').html(html, { /* см. доступные опции https://www.npmjs.com/package/js-beautify#options */ });

Использование

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

PS: Не забываем установить сам модуль: npm i js-beautify --save.

Мне очень нравится идея deps.js т.к. позволяет описывать зависимости не большой простыней, а только там где они нужны. Да и сборку приложения можно организовать достаточно тонко.

Например создать бандл который собирает только js технологию. И при необходимости js можно подключать отдельно на нужную страницу в нужное время.

Существуют даже методы работы с файлами зависимостей, такие как merge BEM.decl.merge(), subtract BEM.decl.subtract()

Но вот опишу задачку. Есть у меня подгружаемые части для SPA. CSS генерится для них и подключаться в сборку главной страницы. HTML же создается шаблонизатором внутри JS файла.

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

При этом, блоки этих частей используют одни и те же JS блоки на 80%.

Соответственно есть идея вынести эти общие блоки так же как и CSS в сборку общего бандла.

И тут не хватает одной команды, которая выдаст общие блоки между несколькими файлами deps.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.

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

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

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

Приветствую! Вопрос, возможно, глупый, но все же хотелось бы узнать мнение людей, которые не такие "зеленые" в этом деле как я. Маленькая предистория: вдохновившись записями мастер-класса BEMup'a в Москве я принялся за дело - сайт получает данные из БД, они обрабатываются в BEMTREE, полученный bemjson в BEMHTML, а оттуда на клиент. Роутингом всего этого занимается express. Все отлично и прекрасно, но есть одно "но". Дело в том, что на всех страницах (точнее сказать по всем адресам, которые знает мое приложение) есть одинаковый контент в виде менюшки, лого и т. д. Так вот хотелось бы всю вот эту, так сказать, "статику" один раз описать в файле *.bemjson и забыть. Очень уж лениво каждый раз после обработки БЕМ-деревом оборачивать полученный bemjson своими блоками, да и если это ajax-запрос, то при таком подходе результат выходит мягко говоря забавный. Думаю, многие сталкивались с подобным, потому буду рад Вашему совету

Скажите, может уже кто реализовывал загрузчик js файлов связанный с Ymodules. Например у меня есть блок ['a'] который зависит от другого блока ['a_m1'] или ['a_m2'].

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

Коротко задача такая: Есть модуль 'a' он уже загружен.


modules.require('a', ['browser'] function(provide, browser) {
        provide( modules.require( 'a_m' ( browser.getName() === 'aurora' ? '1' : '2') ) );
});

А вот модификаторы подгружать только по факту использования.

Кто что-либо делал такое?

Выкручиваясь в объяснениях при рассказе того, что происходит при сборке БЭМ. Нарисовал такую картинку:

bundle (начальная точка сборки) => deps.js (собираем граф) => bemdecl.js (линейная структура зависимостей) => сборка (конкатенация) => компиляция (преобразование типа less=>css)

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

app/
..css/
..../images
......logo.png
....app.css
..app.html

А собирает все обратно в блоки. При этом откровенно мешая работать над исходниками.

Пришлось написать пример с bem-tools + gulp

Где разделил понятия компиляция и сборка таким образом:

  1. bem-tools компилирует файлы исходников в нужный вид раскидывая по папкам блоков
  2. gulp собирает файлы из блоков в ожидаемую структуру.

Так, вот может быть стоит ввести в оборот "сборка/конкатенация файлов для компиляции", "компиляция", "сборка структуры".

Может станет понятнее новичкам?

Ну разные, и что дальше? То, что описывать их в терминах блоков до сих пор больно.

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

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

И откуда начинать работу? Конечно же, со спецификации: https://github.com/bem/bem-forms/blob/dev/BLOCKS.md

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

Но можно и просто початиться с нами в Gitter, пожелать успехов в бою, и всего такого: https://gitter.im/bem/bem-forms

С новым годом! :christmas_tree:

Хочу начать использовать БЭМ в своём небольшом проекте. Переписывать весь html через bemhtml как-то совсем не интересно.

Существует ли какая-то более простая замена, в основе которой будут обычные html-файлы c декларациями блоков? Как-то так:

{{block('title', {text:'Hello'})}}

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

Технология node.js в сборке точно так же, как и browser.js, использует ymodules.

Пользоваться ymodules, где есть npm и CommonJS несколько странно, и появляются вопросы:

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

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

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

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

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

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

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

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

bem-node

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

При сборке бандла выдает такую ошибку

Error: Only literal or function is allowed in template's body at 856:30 block('block1').content()({

at Compiler.assert (путь проекта\libs\bem-core\node_modules\bem-xjst\node_modules\xjst\lib\xjst\compiler\base.js:1 80:9)

at Compiler.transformTemplates (путь проекта\libs\bem-core\node_modules\bem-xjst\node_modules\xjst\lib\xjst\compiler\base.js:648:8)

at Array.map (native)

at Compiler.translate (путь проекта\libs\bem-core\node_modules\bem-xjst\node_modules\xjst\lib\xjst\compiler\base.js:201:41)

at Object.translate (путь проекта\libs\bem-core\node_modules\bem-xjst\node_modules\xjst\lib\xjst\api.js:16:40)

at Compiler.translate (путь проекта\libs\bem-core\node_modules\bem-xjst\lib\bemhtml\compiler.js:121:35)

at Compiler.generate (путь проекта\libs\bem-core\node_modules\bem-xjst\lib\bemhtml\compiler.js:707:14)

at Object.generate (путь проекта\libs\bem-core\node_modules\bem-xjst\lib\bemhtml\api.js:16:40)

at exports.techMixin.getCompiledResult (путь проекта\libs\bem-core.bem\techs\bemhtml.js:46:24)

at _fulfilled (путь проекта\node_modules\bem\node_modules\q\q.js:798:54)

Файл block1.bemtree Содержание

block('block1').content()({ elem: 'elem1' });

Как я понял теперь параметром может быть функция или строка. Но почему? Раньше у меня был bem-core v2.2.1 и там можно было вставлять и объект.

Интересуют все варианты, а не только при использовании всех БЭМ-технологий.

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

Всем привет!

Мы хотим порадовать вас и подарить вам немного БЭМа к новому году!

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

Если вы считаете, что помогли нам и всем БЭМ-разработчикам, напишите, пожалуйста, под этим постом ответы на следующие вопросы:

  • кто вы, где работаете и чем занимаетесь?
  • и
  • какие проекты на БЭМ вы сделали или делаете?
  • какие сайты на БЭМ вы запустили или запустите?
  • какие доклады или статьи про БЭМ вы сделали?
  • если есть что-то еще, добавляйте :)

К ответам приложите, пожалуйста, ссылки на проекты.

Призы мы пришлем почтой, для чего свяжемся с вами.

Начинать можно прямо сейчас!

Удачи и Stay BEMed!

Интересно получить обстоятельный ответ на вопросы о блоке i-bem:

  1. Чем отличается реализация бока в библиотеках bem-core и bem-bl?
  2. Что ждет в будущем реализацию бока в библиотеке bem-bl?
  3. Что мешает выделить его в отдельный пакет? Наличие пакета get-i-bem который тянет реализацию из bem-bl, говорит о наличии такой потребности.
  4. Почему бы не переименовать его в bem.js?

Я использую БЭМ на уровне написания классов. т.е. использую только сам принцип плоских стилей и все. Я выбрал такое пространство имен: 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;
}

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

Приветствую всех! Дошел до изучения i-bem.js и сразу возник вопрос. Я хочу в проекте использовать только этот фреймворк, без остального стека технологий БЭМ. Задав данный вопрос у вас в чатике на Gitter я получил пару ссылок: https://github.com/tenorok/bemer и https://github.com/tenorok/get-i-bem, и вторая в начале меня привлекла, но я так и не смог понять как использовать данный вариант в моем случае. Вот html, который я написал:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" href="static/main.css"/>
    <script src="libs/jquery/dist/jquery.js"></script>
    <script src="libs/i-bem/i-bem.js"></script>
    <script src="common.blocks/b-button/b-button.js"></script>
</head>
<body>
    <button class="b-button i-bem">Click me!</button>
    <button class="b-button b-button_theme_ku i-bem">Click me!</button>
</body>
</html>

А это js:

BEM.DOM.decl('b-button', {
    onSetMod : {
        'js' : {
            'inited': function() {
                this.bindTo('click', function(e) {
                    console.log("Clicked!")
                });
            }
        }
    }
});

Но ничего не работает. Клик не обрабатывается. Возможно я куда-то не туда думаю. Направьте меня, пожалуйста :) Или просто использовать i-bem.js, подключив его на страницу невозможно?

9 years ago

Bc

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

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

.list {
  font-size: 14px
}

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

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

.teaser__list {
  font-size: 18px
}

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

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

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