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

test again

yet another test

Привет!

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

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

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

10 years ago

тест

тест

10 years ago

тест

тест

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

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

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

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

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

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

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

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

10 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']);
  });
};