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

yet another test

Привет!

Блоки должны быть изолированы. Родительские стили не должны на них влиять. Если на сайте, куда я встраиваю свой виджет, указан font-size, то он не должен перебивать размер шрифта в моём виджете. То же касается любых других свойств. Я пробовал решать этот вопрос при помощи postcss-autoreset со сбросом всех-всех стилей. Но если добавлять все css-свойства, чтоб блок в новом окружении НИКОГДА не поехал, то вес стилей же невероятно вырастает. Стилей становится черезмерно много. В связи с этим вопрос:

Какие стили по вашему нужно сбрасывать для блоков?

Насколько я понимаю css, наследуются почти все свойства. А даже если не наследуются, на сайте может быть что-нибудь вроде span {display: block} или более реалистичное a {display: inline-block}, что моему виджету явно помешает. Но как решить эту проблему без разрастания веса моего виджета?

9 years ago

тест

тест

9 years ago

тест

тест

14 мая на сцене Университета ИТМО в Санкт-Петербурге состоится конференция WebDev Talks&Works.

Среди спикеров Антон Виноградов, который расскажет про дизайн-системы глазами и руками разработчика, организацию работы с дизайнерами и вёрстку уровня ”бог“.

Не пропустите!

Новый вебинар по БЭМ совсем скоро!

17 мая в 19:00 мы поговорим об использовании BEMHTML и BEMTREE. Расскажем, как все это можно использовать с любыми источниками данных (файловой системой, базой данных, HTTP API или бэкендом на любом языке).

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

Затронем работу как на сервере, так и на клиенте.

Обратите внимание, трансляция начнется в 19:00 17 мая на отдельной странице.

9 years ago

test

test

Хочу детектить несколько фич. Кажется логичным сделать это через блок ua однако посмотрев код, я не понял как можно добавить свои проверки. В данный момент меня интересует проверка на поддержку fetch API.

Доброго всем времени суток. Долго думал о внедрении БЭМ в проекты... И сейчас назревает новый. Он ещё не утверждён, но я уже обдумываю его реализацию. Планируется следующая схема:

БЭМ (frontend) <-- REST Api --> Express (backend).

Планируется сделать "одностраничное приложение". Но как всегда у меня происходит, в голове всё выглядит как в сказке, но на практике ловлю стопор.

Для вёрстки планирую использовать project stub. Но как правильно подойти к этому моменту?

Опишу вообще как я вижу процесс в абстракции: В проекте лежит каталог bem(project-stub).

Там я верстаю страницы и показываю их заказчику, он радуется. Далее я собранные bemtree + bemhtml подключаю в продакшине. И работаю уже непосредственно с разработанным REST Api + bemtree + bemhtml. В общем стоит задача минифицировать время между вёрсткой демо страниц и продакшин.

Какие здесь подводные камни имеются и реализуемо ли это? Как настроить сборку?

Буду благодарен за ответы :)

Привет! Уже довольно давно ломаю голову, как совокупить БЭМ-подход с регулярно возникающей ситуацией, когда где-то внутри блока нужно разместить один или несколько блоков с тем же названием.

У нас такая практика: есть блок, он описывает DOM-структуру, и к нему через модификатор можно цеплять один из заданных стилей для "раскраски". Например, меню:

<ul class="menu menu_style_main">
    <li class="menu__item"><a href="#" class="menu__link">One</li>
    ...
</ul>

И стили:

.menu_style_main .menu__link {
    font-size:20px;
    color:#F00;
}

...

.menu_style_alt .menu__link {
    font-size:12px;
    color:#666;
}

То есть используем разрешенный методологией каскад "блок-с-модификатором - элемент".

Приключения начинаются, когда дизайнер рисует меню, в котором верхние пункты расхлопываются в попап, внутри которого свой маленький мир, как назло включающий пару вложенных меню. Вот картинка (с первого попавшегося сайта), иллюстрирующая идею: http://joxi.ru/1A5pxGZfK6BoB2

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

Я вижу такие варианты:

  1. Явно описывать в CSS структуру блока, используя "стрелку": .menu_style_main > .menu__item > .menu__link - вроде не труЪ, привязываемся к структуре DOM, вынуждаем себя ее помнить и суппорить изменения в 10 местах.
  2. Спускать модификатор вниз на элементы, то есть вешать на все элементы блока правильный модификатор стиля: .menu__link_style_main etc. Если действовать в таком духе (учитывая, что проблема относится к любому модификатору блока), получим что-то типа pyramid of doom, но в стиле БЭМ - когда 90% html-кода расположены в атрибуте class. Vermicelli of BEM. Как минимум работа со вкладкой Elements консоли разработчика станет очень грустной.
  3. Считать, что это не один блок, а разные (по сути тупо переносим название стиля в имя блока): .menu-main .menu-main__link {...} Во-первых, похоже на предыдущий вариант (приклеиваем название стиля ко всем элементам, только не как модификатор, как часть имени блока). Во-вторых, это все-таки один блок - семантика та же, поведение для JS то же, выглядит только иначе.
  4. Сделать, чтобы вложенное меню на самом деле не было вложенным на уровне DOM (положить рядом и спозиционировать). Неудобно и не реализуемо для других случаев.
  5. Забить на все и тупо инлайнить стили прямо в HTML. Не канает, мы не SPA, собирать это все придется на сервере (а там PHP), и потом еще как-то дублировать поведение на клиенте.

Другие примеры "рекурсивности":

  • блок "таблица" с элементами-ячейками (для рисования лейаутов, внутри ячейки может возникнуть новая "таблица")
  • блок "персона", внутри показываются друзья (тоже "персоны")
  • блок "сообщение на форуме", внутри текста может быть процитировано другое "сообщение на форуме"

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

Кто что посоветует, кто сталкивался с подобными траблами? Сейчас мы используем вариант №1 (селектор прямого потомка), и я склоняюсь к варианту №2 (перенести модификатор на элементы). Потому что зеркалить dom-структуру в CSS приходится руками, а развесить модификаторы мы можем автоматом. И второй вариант вроде бы валиднее с точки зрения методологии.

Расскажите ваши мысли, и может я что-то вообще упускаю? Спасибо )

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

Странное поведение bemhtml. Шаблон:

block('comment-editor').elem('clear').replace()(
    { block : 'input', elem : 'clear', mix : { block : 'comment-editor', elem : 'clear' } }
);

bemhtml output:

<span class="input__clear"></span>

bh.js:

module.exports = function (bh) {
    bh.match('comment-editor__clear', function(ctx){
        return { block : 'input', elem : 'clear', mix : { block : 'comment-editor', elem : 'clear' } };
    });
}

bh.js output:

<span class="input__clear comment-editor__clear"></span>

Как видно, примиксованый блок не появляется. При этом замечена закономерность: Если в миксе или в возвращаемом блоке заменить { elem : 'clear' } на любой другой - микс начинает появляться в коде. Ошибка воспроизводится только когда в блоке и миксе есть одинаковые элементы.

JFYI

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

https://gist.github.com/a-x-/aad7596e2a31bf20f988db1893805a77

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

bemhtml.js

// perf

// classic: 0.1ms..0.2ms
console.time('domik result');
BEMHTML.apply({ block: 'domik' });
console.timeEnd('domik result');

// parallel: fire: 0.1ms, result: 0.5..1ms (x10 slower)
console.time('domik result');console.time('domik fire')
BemhtmlWorkerApply({ block: 'domik' }, html => { console.timeEnd('domik result'); console.log('ololo', html); })
console.timeEnd('domik fire');

Попробовав project-stub, теперь не могу слезть с него. Думаю над проектом уже в виде блоков, элементов, модификаторов и тд. Нужен сервис, бэкенд которого работает только с базой данных. Принимает и отдает в json. Работает на php. Это есть. Но фронтенд должен отвечать за весь функционал, routing, запросы через http request к серверу. Ну вы поняли. Здесь мне нравится angular 2 со встроенным роутингом. Что на счёт bem? Есть решения? Сделав часть проекта на ангуляре втором, понимаешь что не хватает БЭМ(((

Я бы хотел спросить, как правильнее по bem методологии. Имеется bh блок table для таблицы, нужно задать фиксированную ширину колонок только для этой таблицы, есть два способа mix и mod, mix больше кода, у элементов больше на один класс, но зато весь внешний вид в блоке 'orders-table' mod наверное правильнее по методологии, но не явно видно в проекте для дальнейшей поддержки, к тому же будут ещё несколько таблиц со своими размерами.

mix:

{
    block: 'table',
    mix:[{block: 'orders-table'}],
    content:[
    {
        elem: 'colgroup',
        content: [
            {
                elem: 'col',
                mix: [{block: 'orders-table', elem: 'col', mods: {column: 'one'}}],
            },
            {
                elem: 'col',
                mix: [{block: 'orders-table', elem: 'col', mods: {column: 'two'}}],
            }
            ....код таблицы....
    }
]}

mod:

{
    block: 'table',
    mods: {orders:true},
    content:[
    {
        elem: 'colgroup',
        content: [
            {
                elem: 'col',
                mods: {'orders-column':'one'},
            },
            {
                elem: 'col',
                mods: {'orders-column':'two'},
            }
            ....код таблицы....
    }
]}

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

Предистория:

Сейчас работаю с Modx и там имеется возможность создавать блоки кода - Чанки (блоки по методологии БЭМа) и шаблон страниц (Bundles). Но чанки могут в себе подключать другие чанки как в БЭМе блоки. само подключение выглядит следующим образом [[$intro? &name=George&messageCount=12]]

Задача в следующем:

делать 2 версии верстки при билде. 1я это чистая верстка для демонстрации и тд. 2я это возможность нарезать блоки на чанки и определять в них разные плейсхолдеры

Пример

BEMJSON:

{
 block:"list",
 tag: "ul",
 block_rplc:"[[!Wayfinder?  &outerTpl=`list` &RowTpl=`list__item` &activeClass=`list__item--active`]]",
 content_rplc: "[[+wf.wrapper]]",
 content:[
 {
  element:"item",
  tag:"li",
  class_add:"[[+wf.class]]",
  content_rplc: "[[+wf.linktext]]",
  content:"item1",
 },{
  element:"item",
  tag:"li",
  content:"item2",
 },{
  element:"item",
  tag:"li",
  content:"item3",
 } 
]
}

Реализован по БЭМ:

<ul class="list">
 <li class="list__item">item1</li>
 <li class="list__item">item2</li>
 <li class="list__item">item3</li>
</ul>

после нарезки получим 2 чанка list.html

<ul class="list">[[+wf.wrapper]]</ul>

list__item.html

<li class="list__item [[+wf.class]]">[[+wf.linktext]]</li>

а в бандле вместо блока list должны получить следующее:

[[!Wayfinder?  &outerTpl=`list` &RowTpl=`list__item` &activeClass=`list__item--active`]]

Предполагаемое решение:

В BEMJSON при декларировании блоков писать дополнительные поля, которые при сборке используем для нарезки блоков.

Смотрел на днях какой-то доклад, на котором пообещали новую версию сайта bem.info. Когда ожидать?)

Я только начинаю, прошу помочь. Проект сгенерирован в bem-stub. Создаю каталоги блоков (в desktop.blocks), создаю в них стили css. Сами блоки и их элементы отображаются, но их стили нет (применяю простое - поменять цвет шрифта, заливка, обнуляю маржины и пр.). Такое впечатление, что на блоки влияют стили более высокого приоритета, т.к. откуда-то берутся маржины, которые я обнуляю, размеры, которые я не устанавливала. При этом файл desktop.bundles\index\index.css правильно генерирует все стили из моих блоков у себя. В чем может быть причина? Каталоги блоков и их файлы создаю вручную, т.к. команда bem create не работает, ну да это не важно.

Делаю форму как в примере SSSR. Есть несколько полей (блоки input). Если использовать findBlockInside(), то он находит только первый инпут. Мне нужно чтобы все поля были обязательными. Что делать?

Проверяю поля формы как указано в статье про SSSR. Но форма у меня содержит несколько блоков 'input'. А findBlockInside() находит только первый блок, соответственно проверка идет только по первому инпуту. Остальные игнорирует. Что делать?

Хочется чтобы tmpl-specs не падали на шаблонах с i18n. В обычной сборке i18n доступен из this.i18n(). А как сделать, чтобы также было в шаблонах? В шаблонах тоже получается доступно но через this.require('i18n'). Но так не работает в enb server. Для сборки используем enb-bemxjst-i18n

Привожу конфиг

Подскажите, как в шаблоне добавить к блоку модификатор. В bh было просто ctx.mod('name', 'val')

Может быть aria-hidden="true" или aria-hidden. Как попросить диффер считать записи эквивалентными?

Не могу быть уверен, что дело в BEM, но почему то форма не понимает кириллицу и отправляет данные json уже в таком виде. Точнее принимает даже в таком виде.

name=%D0%9A%D0%B8%D0%BC+%D0%A1%D1%82%D0%B0%D0%BD%D0%B8%D1%81%D0%BB%D0%B0%D0%B2+%D0%92%D0%B0%D0%BB%D0%B5%D0%B2%D0%B2%D1%80%D1%8C%D0%B5%D0%B2%D0%B8%D1%87&phone=sdfsdf&email=cyberS7%40mail.ru

Есть ли в i-bem собственный способ получать и отправлять данные (GET/POST) на сервер в json? Например для отправки данных с формы на сервер? Серверная часть написана на PHP (Laravel 5). Общается с фронтендом через API посредством get и post запросов. До этого использовали Vue JS, в нем была возможность общения с сервером из компонента. Интересует тоже самое только через i-bem

Подскажите был ли в bem-bl метод destruct() у блока? Заинтересовал вот этот код. Под bem-core он работать отказывается. Я заменил на BEMDOM.destruct() но вопрос, правильно ли?

Есть блок, в котором есть кнопка и блок с картой от Яндекса. При нажатии на кнопку раскрывается карта. Реализовано через toggleMod. Заменяю текст кнопки через

var button=...
...
button.findElem('text').text("Скрыть")

Как сделать, чтобы при закрытии карты текст в ней снова стал "показать"?

Доброго времени суток, подскажите начинающему, как правильно задавать margin независимым блокам, согласно методологии БЭМ? Ведь блок не должен отвечать за свое позиционирование, а только за шрифты, бокс-модель и прочее, но не margin..?

Добрый день. Кому не сложно, запилите пример использования popup из библиотеки bem-components на чистом проекте project-stub. Пытался подключить как указано в примере на странице компонента, выдает ошибку `popup is not a function'.

Чтобы при сборки в desktop версию падали файлы из desktop.blocks, а в touch соответственно из touch.blocks. Ну и common.blocks был общим.

var fs = require('fs'),
  path = require('path'),
  techs = {
    // essential
    fileProvider: require('enb/techs/file-provider'),
    fileMerge: require('enb/techs/file-merge'),

    // optimization
    borschik: require('enb-borschik/techs/borschik'),

    // css
    stylus: require('enb-stylus/techs/stylus'),

    // js
    browserJs: require('enb-js/techs/browser-js'),

    // bemtree
    // bemtree: require('enb-bemxjst/techs/bemtree'),

    // bemhtml
    bemhtml: require('enb-bemxjst/techs/bemhtml'),
    bemjsonToHtml: require('enb-bemxjst/techs/bemjson-to-html')
  },
  enbBemTechs = require('enb-bem-techs'),
  merged = require('./techs/merged'),
  levels = [
    {path: 'libs/bem-core/common.blocks', check: false},
    {path: 'libs/bem-core/desktop.blocks', check: false},
    {path: 'libs/bem-components/common.blocks', check: false},
    {path: 'libs/bem-components/desktop.blocks', check: false},
    {path: 'libs/bem-components/design/common.blocks', check: false},
    {path: 'libs/bem-components/design/desktop.blocks', check: false},
    {path: 'libs/bem-forms/common.blocks', check: false},
    'common.blocks',
    'desktop.blocks'
  ];

module.exports = function(config) {
  var isProd = process.env.YENV === 'production',
    mergedBundleName = 'merged',
    pathToMargedBundleDesktop = path.join('desktop.bundles', mergedBundleName),
    pathToMargedBundleTouch = path.join('touch.bundles', mergedBundleName);

  fs.existsSync(pathToMargedBundleDesktop) || fs.mkdirSync(pathToMargedBundleDesktop);
  fs.existsSync(pathToMargedBundleTouch) || fs.mkdirSync(pathToMargedBundleTouch);

  merged(config, pathToMargedBundleDesktop);
  merged(config, pathToMargedBundleTouch);

  config.nodes('*.bundles/*', function(nodeConfig) {
    var isMergedNode = path.basename(nodeConfig.getPath()) === mergedBundleName;

    isMergedNode || nodeConfig.addTechs([
      [techs.fileProvider, {target: '?.bemjson.js'}],
      [enbBemTechs.bemjsonToBemdecl]
    ]);

    nodeConfig.addTechs([
      // essential
      [enbBemTechs.levels, {levels: levels}],
      [enbBemTechs.deps],
      [enbBemTechs.files],

      // css
      [techs.stylus, {
        target: '?.css',
        sourcemap: false,
        autoprefixer: {
          browsers: ['ie >= 10', 'last 2 versions', 'opera 12.1', '> 2%']
        }
      }],

      // bemtree
      // [techs.bemtree, { sourceSuffixes: ['bemtree', 'bemtree.js'] }],

      // bemhtml
      [techs.bemhtml, {sourceSuffixes: ['bemhtml', 'bemhtml.js']}],

      // html
      [techs.bemjsonToHtml],

      // client bemhtml
      [enbBemTechs.depsByTechToBemdecl, {
        target: '?.bemhtml.bemdecl.js',
        sourceTech: 'js',
        destTech: 'bemhtml'
      }],
      [enbBemTechs.deps, {
        target: '?.bemhtml.deps.js',
        bemdeclFile: '?.bemhtml.bemdecl.js'
      }],
      [enbBemTechs.files, {
        depsFile: '?.bemhtml.deps.js',
        filesTarget: '?.bemhtml.files',
        dirsTarget: '?.bemhtml.dirs'
      }],
      [techs.bemhtml, {
        target: '?.browser.bemhtml.js',
        filesTarget: '?.bemhtml.files',
        sourceSuffixes: ['bemhtml', 'bemhtml.js']
      }],

      // js
      [techs.browserJs, {includeYM: true}],
      [techs.fileMerge, {
        target: '?.js',
        sources: ['?.browser.js', '?.browser.bemhtml.js']
      }],

      // borschik
      [techs.borschik, {source: '?.js', target: '?.min.js', minify: isProd}],
      [techs.borschik, {source: '?.css', target: '?.min.css', tech: 'cleancss', minify: isProd}]
    ]);

    nodeConfig.addTargets([/* '?.bemtree.js', */ '?.min.css', '?.min.js']);
    isMergedNode || nodeConfig.addTargets(['?.html']);
  });
};