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

Хочется использовать сетку bootstrap в БЭМ. Для этого переделал сетку bootstrap по методологии БЭМ. Саму методологию БЭМ использую только в css. Вроде никаких нарушений нет при внедрении сетки, но т.к. этой методологией только начал пользоваться, хочется услышать мнение профессионалов, может есть какие-либо замечания. Сразу скажу, что библиотеку bem components использовать не желаю, т.к. мне проще верстать элементы самому. Сетку bem grid использовать не приходилось, т.к. уж очень много заморочек при ее интеграции в проект. А вот сам код html:

<div class="container">
    <div class="container__row">
        <div class="container__col container__col_md_4 container__col_xs_6">Блок 1</div>
        <div class="container__col container__col_md_4 container__col_xs_6">Блок 2</div>
        <div class="container__col container__col_md_4 container__col_xs_6">Блок 3</div>
    </div>
</div>

Т.е. блок container так и остался, у него есть элемент containerrow, и обязательный элемент containercol, т.к. модификаторы containercol* нельзя использовать самостоятельно, т.к. с точки зрения БЭМ-методологии модификатор не может использоваться в отрыве от модифицируемого блока или элемента.

Очень надеюсь на ответ. Спасибо!

Вопрос про физическое наименование/расположение папок и файлов для подсовывания enb.

Для модикатора использую _modName/blockName_modName.*, для элемента __elemName/blockName__elemName.*.

А для элемента блока с определённым модификатором. Вопреки ожиданиям, _modName__elemName/... не работает. Хотя для _modName1_modName2, напр., -- запросто.

Есть к.-то паттерн подходящий?

Всем привет! Наткнулся с небольшой проблемой, хотелось бы узнать как кто ее решает Для начала bemjson:

{
  block: "page"
  ...
  content : {
        block : 'wrapper',
        js : true,
        content : [
            {
                block : 'popup',
                mods : { theme: 'islands', target : 'anchor' },
                directions : ['bottom-center'],
                content : 'Содержимое всплывающего окна'
            },
            {
                elem : 'show',
                content: {
                    block : 'button',
                    mods: { theme : 'islands', size: 'm' },
                    text: 'Показать'
                }
            },
            {
                elem : 'hide',
                content : {
                    block : 'button',
                    name: 'hide',
                    mods: { theme : 'islands', size: 'm' },
                    text: 'Скрыть'
                }
            }
        ]
    }
}

и wrapper.js

modules.define('wrapper', ['i-bem__dom'], function(provide, BEMDOM){
    provide(BEMDOM.decl(this.name,
        {
            onSetMod : {
                js : {
                    inited : function () {
                        this.findBlockInside('popup').setAnchor(this);
                        this.findBlockInside('show', 'button')
                            .on(
                                'click',
                                this._onShow,
                                this
                            );
                        this.findBlockInside('hide', 'button')
                            .on(
                                'click',
                                this._onHide,
                                this
                            );
                    }
                }
            },
            _onShow : function () {
                this.findBlockInside('popup').setMod('visible', true);
            },
            _onHide : function () {
                this.findBlockInside('popup').setMod('visible', false);
            }
        }
    ));
});

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

this.findBlockInside('popup').setMod('visible', true);

поиск popup'a дает null и соответсвенно setMod сыпит. Все происходит потому, что узел с окошком меняет свое местоположение в дереве и из любой вложенности "перепрыгивает" вконец узла body. Конечно можно написать что-то типа этого

modules.define('wrapper', ['i-bem__dom'], function(provide, BEMDOM){
    var popup;
    provide(BEMDOM.decl(this.name,
    ...
                    inited : function () {
                        popup = this.findBlockInside('popup').setAnchor(this);
    ...

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

Добрый день! Сразу говорю, документацию не читал, в философии не разбирался. Вопрос только один. Существует достаточно много js библиотек для построения интерфейса. У некоторых из них (ext.js, smartclient, webix, qooxdoo и пр.), есть возможность писать представление прямо в javascript по способу, очень похожему, который описан в bemjson. Это я считаю очень удобно, код получается чистым. А у некоторых из них сделано все это не очень красиво: аля jquery ui. Т.е цепляемся к определенным dom элементам по css селектору и прописываем в js свойства. Такой метод конечно хорош для простого сайта, но для полноценной SPA - не очень приятно. Например кнопки тулбара одна библиотека хранит в json, а сам тулбар цепляется к dom элементу, другая требует чтобы обязательно див элементы на эти кнопки и т.п.. В результате получается бардак. За примером далеко ходить не надо, посмотрите easyui, jQWidgets, kendo UI и тп. Я хочу писать подобные вещи без строчки html кода. Сможет ли bem превратить json код в что-то аля:

<body>
   <input id = ‘spinner’ class="easyui-numberspinner" 
</body>
<script>
$('# spinner’). numberspinner ({increment:10});
</script>

Доопределяю через модификтор блок input для работы с датами (выбор из всплывающего календаря, преобразования js-date/readable string). Испольую mods : { date : true } и, соотв.:

modules.define('input', [ ... ], function (...) {
    provide(Input.decl({ modName : 'date', modVal : true }, {
        /* мой код модуля */
    } ));
});

Могу ли по аналогии с расширением класса использовать методы блока-родителя? Т.е., напр. определить свой метод setVal(), который будет передавать преобразованное значение родительскому методу setVal()?

Думал достучаться через this.__base, но примеров такого подхода не обнаружил.

Это возможно? Как?

Есть желание реализовать автосохранение текущего состояния SPA интерфейса в центральном хранилище, возможность передать его как JSON, как URL и загрузить обратно из JSON/URL.

Т. е. у части блоков имеется не-BEM имя ~ как имя инпута HTML-формы. Как правильно по BEM реализовать такой глобальный функционал? Как лучше хранить данные типа input type=hidden, не имеющие своих блоков?

Касательно стилей mustDeps - гарантированное нахождение блока до текущего; shouldDeps - просто включение в сборку

Нормальная ли практика - в *.deps.js файле блока указывать зависимости от его элементов и модификаторов?

Для того, чтобы подключать этот блок в депсах другого одной строкой { block: 'b1' }, а не перечислением всех необходимых модификаторов данного блока. И для того, чтобы неиспользуемые на песочнице модификаторы backend уже на свое усмотрение мог юзать.

Настоящим постом хочу продемонстрировать вам как будет выглядет API bem-xjst v8.x. Все пока на стадии RC, поэтому хочу выслушать ваше мнение по поводу всего этого.

Изменения, которые войдут в v8.x

  • Все режимы теперь ведут себя одинаково: переопределяют значение из BEMJSON. (major)
  • Добавлены недостающие режимы: mods() и elemMods() для установки модификаторов. (minor)
  • Добавлены шорткаты режимов для добавления: addMix(), addAttrs(), addMods(), addElemMods(), addJs(). (minor)
  • Добавлены шорткаты для добавления content: appendContent() и prependContent(). (minor)

TLDR; Песочница bem-xjst v8.x RC: https://goo.gl/ZeY4xL, в которой можно попробовать все эти вкусности…

Технические подробности

1. Все режимы теперь ведут себя одинаково: переопределяют значение из BEMJSON. (major)

Сейчас значение из шаблона режима content(), bem(), cls(), tag() переопределяет значение указанное в BEMJSON. Если вам нужно расширить значение из BEMJSON в шаблоне нужно использовать applyNext() и this.extend()/concat().

Однако режимы mix(), js(), attrs() сейчас расширяют значение из BEMJSON.

Разное поведение режимов вносит некоторый раздрай и постоянно приходится держать в уме кто как себя ведет.

В v8.x мы привели все режимы к одинаковому явному поведению: переопределение значения из BEMJSON. Если вам нужно добавить что-либо, то теперь это можно будет сделать в явном виде — см п.3.

2. Добавлены недостающие режимы: mods() и elemMods() для установки модификаторов. (minor)

Под капотом эти режимы просто шорткаты к уже привычным всем конструкциям:

// mods()({something: myValue})
def()(function() {
    this.mods = {something: myValue};
    return applyNext();
});

и

// elemMods()({something: myValue})
def()(function() {
    this.elemMods = {something: myValue};
    return applyNext();
});

Как видно из примеров режимы mods() и elemMods() не имеют своей собственно очереди шаблонов, а добавляют шаблоны в стек к режиму def().

По умолчанию mods() и elemMods() возвратят вам значения из this.mods и this.elemMods соответственно.

Пример:

// BEMJSON
{ block: 'b' }

//Шаблоны
block('b').def()(function() {
  return JSON.stringify(apply('mods'));
});

//Результатом будет:
[]

3. Добавлены шорткаты режимов для добавления: addMix(), addAttrs(), addMods(), addElemMods(), addJs().

Так как все режимы теперь переопределяют значение, то чтобы компенсировать необходимость писать applyNext() для накапливания результата были введены шорткаты для уже существующих режимов add*().

Под капотом addJs()({ somekey: someval }) это

js()(function() {
  return this.extend(applyNext(), { somekey: someval });
});

Под капотом addMix()({block: 'mixed' }) это

mix()(function() {
  var res = applyNext();
  if (!Array.isArray(res)) res = [ res ];

  return res.push({block: 'mixed' })
})

Для остальных режимов аналогично. Как видно из примера шорткаты add*() не имеют своего стека шаблонов, а просто добавляют шаблон в стек соответствующего режима.

И, естественно, вы можете накапливать результат:

// Шаблоны
block('b')(
   addJs()({ a: 1 })
   addJs()({ b: 2 })
   addJs()({ c: 3 })
);

// BEMJSON
{ block: 'b' }

// Результат:
<div class="b b_type_awesome i-bem" data-bem='{"b":{"a":1,"b":2,"c":3}}'></div>

4. Добавлены шорткаты для добавления content: appendContent() и prependContent().

// Шаблоны:
block('b')(
    appendContent()(', templates!'),
    appendContent()('!!1'),
    prependContent()('(〜 ̄▽ ̄)〜 ')
);

// BEMJSON
{ block: 'b', content: 'Hello' }

// Результат:
<div class="b">(〜 ̄▽ ̄)〜 Hello, templates!!!1</div>

Как вы уже наверное догадались, это тоже шорткаты и они добавляют шаблоны в стек режима content(). Пример:

// appendContent()(', templates!') это тоже самое что и:
content()(function() {
  return [
    applyNext(),
    ', templates!'
  ];
});

Есть задача менять (добавлять, удалять) пункты меню в выпадающем списке (menu в select).

Сойчас решаю проблему полной перегенерацией блока. Примерно так: BEMDOM.update(..., BEMHTML.apply(...)). Пока встречается не очень часто, но как-то всё же не красиво, да хотелось бы иметь способ на будущее.

Похожий способ, но тоже не очень вариант: в select есть доступ к вложенному menu (свойство _menu) методом setContent заменять содержимое на сгенерированный html.

Можно ли придумать способ, чтоб это было похоже на оперирование с элементами массива или через интерфейс inset/append/remove? Ну хоть как-то вообще?

Есть нужда написать десктопное приложение на electron и большое желание использовать БЭМ (bemhtml, i-bem.js, bem-core, bem-components) для верстки UI. Кто в теме, подскажите как подойти к задаче. С БЭМ есть неплохой опыт, а вот с electron практически не знаком.

Добрый день. Немного предистории.

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

Так как почти все страницы в проекте имеют бизнес-логику, страницы не используют bemjson и строятся по технологии bemtree, и соответственно блоки покрыты deps.js Тогда я начал костылять утилиту, которая строила граф по deps.js и визуализировала его (На примере bem-components http://eugenegantz.ru/page/bem-dep-gr-link_pseudo/)

Но видно, что это неполноценное решение:

  • Неточная структура шаблонизируемого дерева (хотя для редактирования должно быть достаточно)
  • Нет гарантий если разработчик упустил что-нибудь при оформлении deps.js, или например, зная контекст вынес deps на другой уровень
  • Необходимо использовать доп. утилиты на случай bemjson

В итоге такой вопрос знатокам: Существует ли адекватный способ производить поиск по БЭМ сущностям в проектах и строить структуру проекта?

К примеру, на случай если в проекте новый человек или проект ведут много специалистов.

Потому что мне думается что-то уже должно было быть придумано для таких случаев.

Привет ! Просьба помочь с настройкой gemini. Есть компьютер на Ubuntu. На нём есть nginx с тестовыми примерами для gemini. Поднят тутже selenium hub. К hub-у подключён node с виртуалки. Виртуалка - virtualBox - win7 - ie11. Запускаю gemini тест - на виртуалке открывается окно браузера - с светло зелёным экраном. Как я понял - это цвет какого-то джеминевского калибратора. Но дальше тесты не запускаются. Через какое-то время Gemini падает с ошибкой, что не удалось запустить ie11 - ETIMEDOUT. gemini.conf http://pastebin.com/7meB32Wt тест http://pastebin.com/CNW10GyS конфигурация Selenium node http://pastebin.com/tR6yDxcn вресия selenium 2.53.1 gemini 4.4.1, 4.8.0, 4.9.0

Пробовал делать скриншоты, используя nightwatch.js и там всё проходило отлично. Продублирую, на всякий случай в issue

Привет!

Мы приготовили для вас демо-проект на ASP.NET MVC, иллюстрирующий решение типовых задач с помощью БЭМ-инструментов.

В readme подробно описано, как всё работает. Вы можете не только посмотреть исходный код, но и запустить демо-приложение на своем компьютере, чтобы попробовать в действии!

Завтра буду рассказывать про БЭМ и ASP.NET на Я.Субботнике. Подключайтесь к трансляции!

Ребята, можно ли так?

modules.define('finolog-programm-list__list-item', ['i-bem__dom', 'BEMHTML', 'jquery'], function(provide, BEMDOM, BEMHTML, $ ){
   provide(BEMDOM.decl(this.name,{
       //методы экземпляра блока
       onSetMod:{
           'js': {
               'inited': function(){

               }
           }
       }
   }));
});

Вроде, ничего криминального. Но не хочет работать

Есть утилиты которые атомарно изменяют DOM не используя virtual DOM. Есть мысль прикрутить morphdom к i-bem.js. Однако, есть сомнения что затея сработает. Например, непонятно что будет с событиями, будут ли инициализироваться блоки. Кто в теме подскажете в какую сторону копать?

По запросу в поисковик "i-bem__dom_init_auto" я нашел кучу незавершенных тем. Решился написать на форум, увидев, что подобным интересуюсь не только я. Думаю, понятно о чем пойдет речь. Стоит сразу 2 задачи: вынести ym, jquery, i-bem и т.д в отдельный файл, и заводить не по domReady. Хотелось бы решить максимально не велосипедя.

Прямо в документации сказано: noDeps (массив/объект) — можно отменить какую-то зависимость (например, i-bem__dom_init_auto).

Хотя, как я понимаю, принято категорически избегать noDeps. Видимо, по тем же причинам что и !important в css. Так или иначе, не могу его исплючить из финального deps, он все равно приезжает. Ну и если кто-то найдет этот пост, дабы уж не разметать все по кускам, напишу тут, что, по-идеи, достаточно собрать бандл с ym и блоком 'page'. А уж потом можно вторым файлом бандл со своими блоками лепить. Но! Тут то и встает у меня основная проблема.

Представим,что у нас такая картина:

//ym, i-bem и вот это все.
<script src="/assets/bootstrap/bootstrap.js" type="text/javascript"></script>
//В этом бандле один единственный блок
<script src="/bundles/index/index.js" type="text/javascript"></script>

Не работает. И нет ошибки в консоли. i-bem__dom_init_auto находится в конце файла bootstrap.js - не работает. Подрубаю к моему к моему index.js в сборку i-bem. Теперь мой блок находится в одном файле с i-bem__dom_init_auto, и все еще ниже него. Результат: теперь работает. Я бы и не против замешивать "стартер" с ручным вызовом в каждый свой бандл, кода то там совсем чуть-чуть. Но как тогда исключить его из сборки bootstrap.js?

Такая же проблема будет если просто взять https://yastatic.net/bem-components/latest/touch-pad/bem-components.js.Но там мои блоки хотя бы через раз работают. Да, именно так. Просто сижу и тыкаю ctrl + r, иногда код не отрабатывает. (Могу даже дать ссылку боевого сайта, где такая проблема) Успел твой файл скачаться до инициации? Ну и ладненько, радуйся.

Казалось бы, логичный кейс. Зачем мне заворачивать все в один бандл, если страниц на сайте много? Я ведь не ландинг делаю, пущай в кэш браузера запомнит основу. Давайте наконец-то разберемся.

Заказчик утверждает что это не бэм: https://yadi.sk/i/_C_xzUD4uazU7 Есть у меня список постов на одной из страниц который идет обычном списком вниз, 1 пост 1 ряд. Я с помощью --inline модификатора для главной страницы переделал данный блок постов в ряд, по 4 поста в ряд теперь. Это БЭМ или нет? И если нет как правильно? Вешать класс на каждую вьюху?

Как то давно, мной был задан вопрос https://ru.bem.info/forum/793/ по реализации разделения css стилей и последующего их инлайна на html страницу.

Подход довольно простой.

  1. Собираем два разных бандла, первый critical, второй со всеми стилями.
  2. Превращаем файл critical.css в js файл, через инлайн файла module.exports = '....'
  3. Подключаем этот файл обычным require в виде элемента блока page {elem: 'css', content: require('desktop.bundles/critical/critical.css.js')}

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

Выложил выжимку своего конфига на enb https://gist.github.com/JiLiZART/efa6b23c478b17c4708b931a44fce996

Я использую bemtree, но для bemjson будет даже проще.

Есть у этого способа и недостатки, стили, которые инлайнятся в страницу, дублируются в бандле со всеми остальными стилями. Для решения этой проблемы я навоял вычитание deps'ов друг из друга в этом PR https://github.com/enb/enb-bem-techs/pull/190 Что поможет в дальнейшем вычитать все блоки critical бандла из основного

Привет! Хочу рассказать о полезной штуке, которую мы написали в Яндекс.Директе.

direct-dev-server - это веб-сервер для заданной ENB-ноды с автоматической пересборкой бандлов при изменении исходных файлов. Сервер имеет кэш и собирает бандлы только если исходные файлы изменились (в отличие от enb-server, который собирает при каждом http-запросе).

Его удобно использовать тогда, когда нужно часто менять код и пересобирать бандлы (например, во время отладки кода блоков). За счет того, что сборка запускается сразу же при изменении файлов и за счет использования кэша готовый для отладки набор бандлов формируется намного быстрее, чем, например, при использовании ENB в режиме сервера.

Как использовать

  1. Устанавливаем
npm i direct-dev-server
  1. Запускаем
node node_modules/direct-dev-server -b <название_бандла>
  1. В консоль выводится ссылка, открываем ее в браузере

    Конфигурационный файл

Конфигурационный файл должен лежать в корневой директории и называться .dev-server.js.

Пример:

module.exports = {
    bundles: 'bundles',             // папка с бандлами
    levels: [                       // список уровней переопределения
      'common.blocks'               // (в них будут отслеживаться изменения файлов)  
      'desktop.blocks'
    ],     
    defaultTarget: '?.test.html',   // таргет начальной страницы (будет открыта в браузере при старте)
    targets: {                      // зависимости таргетов от БЭМ-технологий
        '?.js': ['js'],
        '?.test.js': ['test.js'],
        '?.css': ['css']
    }
};

Пытаюсь настроить enb на простую сборку js и css, без bemhtml. Возможно ли получать bemdecl на лету, на основе html, при помощи этого:

https://github.com/bem-contrib/html2bemjson

Попытался написать даже свою технологию для enb, но как я понимаю, она смотрит только на уровни переопределения, когда уже есть готовый bemdecl.

Вроде, даже json адекватный выходит, если ручками прогнать. Но как сагрить на все это сборщик?

Опубликовали два новых документа по методологии

Быстрый старт: https://ru.bem.info/methodology/quick-start/

БЭМ для CSS: https://ru.bem.info/methodology/css/

Приятного чтения :)

При добавлении select после загрузки страницы, данный select не работает.

При взаимодействии с созданным select в консоли браузера появляется ошибка:

Uncaught TypeError: Cannot read property 'setMod' of undefined.

Подключенные файлы: bem-components-dist/desktop/bem-components.css bem-components-dist/desktop/bem-components.js+bemhtml.js

JS:

modules.define('filter-form', ['i-bem__dom'], function(provide, BEMDOM) {

                provide(BEMDOM.decl(this.name, {
                    onSetMod: {
                        js: {
                            inited: function() {
                                this.findBlockInside('select').on('change', function() {
                                    var value = this.getVal();

                                    console.log(value);
                                });
                            }
                        }
                    }
                }));

            });

Подскажите пожалуйста как решить данную проблему?

Как правильно удалять блоки? Делаю BEMDOM.destruct(...), но остаются подписки на события. В доках/коде пока решения откопать не удаётся

Переношу пост @avprinciple из https://github.com/bem/bem-forum-content-en/issues/38 Ниже цитата:

Приветствую!

Как избежать большого кол-ва элементов от 1 блока? Проблема возникает, когда много элементов в блоке, но нужно сохранить зависимость от родительского блока.

Sample

  <section class="meet-us">
    <div class="container">
      <h3 class="meet-us__title heading-3">Meet Us</h3>
      <div class="meet-us__items">
        <div class="meet-us__item">
          <img class="meet-us__img" src="img/team-1.jpg" width="269" height="355" alt="Team member">
          <div class="meet-us__info">
            <h5 class="meet-us__name">Kirkorov</h5>
            <p class="meet-us__metier">Babo-pinatel</p>
            <div class="meet-us__social"> <!--  overlay/display:none -->
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#behance"></use>
                </svg>
              </a>
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#facebook"></use>
                </svg>
              </a>
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#twitter"></use>
                </svg>
              </a>
            </div>
          </div>
        </div>
        <div class="meet-us__item">
          <img class="meet-us__img" src="img/team-2.jpg" width="269" height="355" alt="Team member">
          <div class="meet-us__info">
            <h5 class="meet-us__name">Putin</h5>
            <p class="meet-us__metier">reshala</p>
            <div class="meet-us__social">
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#behance"></use>
                </svg>
              </a>
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#facebook"></use>
                </svg>
              </a>
              <a href="#" class="meet-us__link">
                <svg class="meet-us__icon">
                  <use xlink:href="img/icons.svg#twitter"></use>
                </svg>
              </a>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>

Вместо:

<div class="meet-us__item">
и далее...

или внутри него писать новый блок, например card и:

        <div class="card">
          <img class="card__img" src="" alt="">
          <div class="card__info">
            <h5 class="card__name">Nam</h5>
            <p class="card__metier">Profession</p>
            <div class="social card__social">  <!-- Тут ещё один блок social  -->
              <a href="#" class="social__link">
                <svg class="social__icon">
                  <use xlink:href="img/icons.svg#behance"></use>
                </svg>
              </a>
              <a href="#" class="social__link">
                <svg class="social__icon">
                  <use xlink:href="img/icons.svg#facebook"></use>
                </svg>
              </a>
              <a href="#" class="social__link">
                <svg class="social__icon">
                  <use xlink:href="img/icons.svg#twitter"></use>
                </svg>
              </a>
            </div>
          </div>
        </div>
  1. Правильно ли я разметил по БЭМ-у в 1 примере?
  2. Как мне сохранить зависимость/наследование/связь от родительского блока, то есть meet-us, или если я блок card вставлю внутри meet-us__item, то от него. Добавлять к блоку card второй класс meet-us__card? И как вообще правильно делать?)

Ещё где-то я видел в исходниках какого-то сайта примерно такое:

<div class="block">
  <div class="block__items">
    <div class="block__item">
      <h3 class="block__item-title">BEM</h3>
      <p class="block__item-text">BEM is wow</p>
      <div class="block__item-media">
        <img src="" alt="" class="block__item-img">
      </div>
      <div class="block__item-social">ya.ru</div>
      <div class="block__item-action">More</div>
    </div>
  </div>
</div>

Как вариант?

И видели ли документацию mdl (Material design light)? Пример:

<ul class="demo-list-two mdl-list">
  <li class="mdl-list__item mdl-list__item--two-line">
    <span class="mdl-list__item-primary-content">
      <i class="material-icons mdl-list__item-avatar">person</i>
      <span>Bryan Cranston</span>
      <span class="mdl-list__item-sub-title">62 Episodes</span>
    </span>
    <span class="mdl-list__item-secondary-content">
      <span class="mdl-list__item-secondary-info">Actor</span>
      <a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
    </span>
  </li>
</ul>

Я просто в документации такого рода примера не заметил или пропустил, верно ли так? Вместо mdl-list__avatar, они пишут: mdl-list__item-avatar, и вообще от элемента mdl-list__item, они создают несколько блоков ниже, они так сохраняют связь, логику от имени item, но правильно ли это, или они так интерпретируют BEM под себя? Это хороший пример, когда много блоков/а точнее элементов внутри. Например, в моём первом примере уже есть meet-us__title, я всё от блока meet-us и размечал, элементами, а вдруг внутри meet-us__item у меня завтра появится ещё заголовок, я уже не смогу написать meet-us__title, так как занято, могу конечно написать meet-us__heading, а гугл в (MDL) написал бы meet-us__item-title, они так избегают элемент в элементе - meet-us__item__title, правильно ли будет делать так как они?

Спасибо.

Русская версия форума у меня не работает, ошибка 500, а до этого пост не мог написать, как и на английской версии, поэтому пишу тут.

Необходимо подключить редактор tinyMCE на проект. И вот тут я не могу сообразить, как это сделать. Ранее подключал и jQuery-плагины и небольшие скрипты вроде clamp.js. Там было достаточно просто:

  1. беру код функции (например, clamp.js),
  2. оборачиваю его в блок,
  3. делаю provide функции для использования блоками
  4. в блоках прописываю зависимость и использую уже внутри Пример:
modules.define('js-clampJS', ['jquery'], function(provide, $) {
    /*!
     * Clamp.js 0.5.1 Copyright 2011-2013, Joseph Schmitt http://joe.sh ...
     */

    (function(){
      function clamp(element, options){...}
      window.$clamp = clamp;
    })();

    provide($clamp);
});
modules.define('company-ads-clamp', ['i-bem__dom', 'BEMHTML', 'jquery', 'js-clampJS'], function(provide, BEMDOM, BEMHTML, $, $clamp) {
    provide(BEMDOM.decl(this.name,
   { ... }));
});

Код этого редактора построен по своей модульной структуре. Не знаю, как провайдить его для использования другими блоками. Вот небольшая часть его кода:

(function(exports, undefined) {
    "use strict";
    var modules = {};
    function require(ids, callback) {}
    function define(id, dependencies, definition) {}
    function resolve(id) {}
    function expose(ids) {}
     ... 
    expose([...]);
})(this)

Подскажите, как действовать, если сталкивались с чем-то похожим.

Возможно ли настроить сборку для обхода по коротким названиям ресурсов блоков?

вместо: {block}/{block}.{tech}

использовать: {block}/{tech}

2016-08-15 23-42-02

По поводу плюсов длинного именования я в курсе, но и по поводу минусов тоже. Тем более что в основном для навигации пользуюсь fuzzy-поиском. 2016-08-15 23-42-55

Сейчас:

block-super-long/block-super-long.css
block-super-long/block-super-long.deps.js
block-super-long/block-super-long.bemtree.js
block-super-long/block-super-long.bemhtml.js
block-super-long/__elem/block-super-long__elem.css
block-super-long/__elem/_modifier/block-super-long__elem_modifier_value.css

Короткий вариант:

block-super-long/style.css
block-super-long/deps.js
block-super-long/bemtree.js
block-super-long/bemhtml.js
block-super-long/__elem/style.css
block-super-long/__elem/_modifier_value/style.css

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

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

Проблема довольно банальна - ссылка на картинку блока из CSS файла блока не работает. Единственный работающий вариант это:

...
background-image: url(../../common.blocks/header/images/bg-header.png)
...

Фактически это абсолютный путь к блоку, в который так-же входит и путь к папке блоков common.blocks, что на мой взгляд совершенно неверно. Т.е. если я допустим захочу вынести потом этот компонент в допустим папку blog.blocks то получается надо будет бегать и пути менять. Или переименую я блок - та-же история.

Вот такой вариант:

...
background-image: url(images/bg-header.png)
...

работать отказывается

Borschik (через enb - project-stub) чё-то как-то не помог - такой путь он просто проигнорировал. Пытался крутить конфиг .borschik но без особого успеха (но тут я сильно глубоко не рыл).

Итого вопрос - как всё-таки идеологически верно указывать пути к картинкам блока в CSS-файлах блока?

Хочу в этой теме обсудить структуру проекта по бэму для верстальщика. Верстальщиком называю человека, который превращает PSD в html/css и немного js. Фронтендеры пишут жирный JS и БЭМ :)

Начну из далека. У обычных верстальщиков структура примерно такая (взято из TARS):

static/                                     #  Folder for static-files. You can choose the name for that folder in tars-config.js
    └── fonts/                              # Fonts (can contain subdirectories)
    └── img/                                # Images. You can choose the name for that folder in tars-config.js
        └── content/                        # Images for content (can contain subdirectories)
        └── plugins/                        # Images for plugins (can contain subdirectories)
        └── general/                        # General images for project (can contain subdirectories)
        └── sprite/                         # Raster images, which is included in png-sprite.
            └── 96dpi/                      # Images for displays with dpi 96
            ...
            └── 384dpi/                     # Images for displays with dpi 384 (more info in images-processing)
        └── svg/                            # SVG-images
    └── js/                                 # js
        └── framework/                      # js-frameworks (backbone, for example)
        └── libraries/                      # js-libraries (jquery, for-example)
        └── plugins/                        # js-plugins
        └── separate-js/                    # js-files, which must not be included in ready bundle
    └── misc/                               # General files, which will be moved to root directory of ready project — favicons, robots.txt and so on  (can contain subdirectories)
    └── scss  
        ├── entry/                          # Styles for entry points for css in case of manual css-processing More info [here](css-manual-processing.md).                
        └── etc/                            # Styles, which will be included in the end of ready css-file (can contain subdirectories)
        └── libraries/                      # Styles for libraries (can contain subdirectories)
        └── plugins/                        # Styles for plugins (can contain subdirectories)
        └── sprite-generator-templates/     # Templates for sprite generating
        └── sprites-scss/                   # Mixins for sprites
        ├── separate-css/                   # Css-files, which must not be included in ready bundle
        ├── common.scss                     # General styles
        ├── fonts.scss                      # Styles for fonts
        ├── GUI.scss                        # Styles for GUI elements (inputs, buttons and so on)
        ├── mixins.scss                     # Project's mixins
        ├── normalize.scss                  # Styles reset
        ├── vars.scss                       # Variables

Всё разделено по реализациям и технологиям, и всё инклюдится :)

В бэме эту структуру перевернули с ног на голову и засунули всё в блок.

button
  button.css
  button.js

Допустим у нас одностраничный сайт, и все блоки лежат плоской структурой. Уровней переопределения нет.

project
  index.html
  static
    header
    footer
    button
      button.css
      button.js

Если у нас несколько страниц сайта, то появляется необходимость выделить блоки страниц на отдельный уровень переопределения. К тому же, в этом проекте воспользовались несколькими сторонними библиотеками блоков, которые тоже следует выделить на отдельный уровень переопределения. Уже на этом этапе встает вопрос о том, как удобней и универсальней это сделать.

Первый вариант я подсмотрел в исходниках сайта bem.info.

project
  about.html
  index.html
  static
    blocks
      about               # 3 level
        button
      common              # 2 level
        button
      index               # 3 level
        button
    libs                  # 1 level
      foo-components
        button

Для меня основное неудобство этого варианта в том, что общие блоки common визуально смешиваются и теряются в дереве каталогов страниц.

Второй вариант - это явно указать где что лежит.

project
  about.html
  index.html
  static
    common                # 2 level
      button
    libs                  # 1 level
      foo-components
        button
    pages                 # 3 level
      about
        button
      index
        button

Остановимся на втором варианте. Теперь нам нужно сделать мобильную версию сайта. У нас уровни переопределения будут разветвляться на платформы desktop и mobile. При этом блоки common из общих для всех страниц, превращаются в общие для платформ.

Вариант "в лоб".

project
  about.html
  index.html
  static
    common                # 2 level
      button
    libs                  # 1 level
      foo-components
        button
    desktop
      common              # 3a level
        button
      pages               # 4a level
        about
          button
    mobile
      common              # 3b level
        button
      pages               # 4b level
        about
          button

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

Можно эту структуру представить в плоском виде. При этом в названиях папок через точку определять ее "тип". В этом месте мы подбираемся к "бэму головного мозга". Добавим к этому, что источников библиотек у нас стало несколько (допустим, они не пересекаются в плане используемых блоков).

project
  about.html
  index.html
  static
    bower.libs
      foo-components
        button
    common.blocks
      button
    desktop.blocks
      button
    desktop.pages
      about
        button
    mobile.blocks
      button
    mobile.pages
      about
        button
    npm.libs
      bar-components
        input

Схлопнутый вариант:

bower.libs
common.blocks
desktop.blocks
desktop.pages
mobile.blocks
mobile.pages
npm.libs

Если для генерации html использовать шаблонизаторы, то их можно хранить внутри блоков, либо как технология проекта *.templates.

Резюмируя, у меня получается такая структура проекта. Для собранной верстки с последующей отдачей бэкендерам, можно предусмотреть папки в технологии *.dist.

bower.libs
common.blocks
common.templates
desktop.blocks
desktop.dist
desktop.pages
desktop.templates
mobile.blocks
mobile.dist
mobile.pages
mobile.templates
npm.libs

Хочется определиться со структурой и придерживаться ее во всех проектах любой сложности. Надеюсь на вашу помощь в плане того, правильно ли я понял и применяю идею технологий реализации проекта как блока. Также очень интересно узнать как бы вы по бэму положили в проект шрифты, спрайты, переменные и миксины (SCSS, LESS).

Нужно получать на выходе файл с шаблонами бандла без обёрточного кода BEM-XJST (BEM-XJST User-code Start ... BEM-XJST User-code End).

Пока придумал добавить свою технологию, которая из имеющегося .bemhtml.js создавала к.-ндь .bemhtml.raw.js, выкусывая всё, кроме шаблонов.

Есть ли более изящный способ?

В опциях к самому techs/bemhtml ничего годного не вижу.