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

Есть ли возможность заставить bem-xjst генерировать HTML в таком виде:

<button class="b-button b-button_size_large">Label</button>

вместо:

<button class="button button_size_large">Label</button>

Приветствую! Не понимаю. Подскажите пожалуйста, допустимо ли применение нескольких элементов БЭМ на одном теге?

.block-a
  .block-b
    .block-a__elem.block-b__elem

Ну, и попутно вопрос по вложенности. Допустимо ли такое:

.block-a
  .block-b
    .block-a__elem.block-c
      .block-b__elem
        .block-c__elem
3 months ago

э

д

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

Отсюда вопрос:

  1. Как мне оформлять данную кнопку с точки зрения БЭМ, как элемент блока header или как элемент блока search?
  2. Допустимо ли во вложенном блоке использовать элементы блока родителя?

Заранее, благодарю.

<header class="header">
    <div class="search header__search">
        <form class="search__form" action="/" method="post">

                    <button type="submit" class="search__submit">
                        <i class="icon icon--search"></i>
                        <span>Найти</span>
                    </button>

                    <input class="search__input" placeholder="Поиск товаров" type="text" name="search">

                    <a class="search__extended" href="#">
                        <i class="icon icon--gear--outline"></i>
                        <span>Расширенный поиск</span>
                    </a>

                    <!-- Кнопка ЗАКРЫТЬ -->
                    <button class="header__search-close">
                        <i class="icon--cancel"></i>
                    </button>

                </form>
    </div>
</header>

Cuprite — ещё одно open-source решение, разработанное нашей командой. Это драйвер для Capybara, который позволяет использовать Ferrum без переключения между API. Ferrum + Capybara = Cuprite Cuprite — это драйвер для Capybara, который использует Ferrum — драйвер на чистом Ruby с минимальным количеством зависимостей для запуска headless Google Chrome.

О том, как:

  • Начать работать с Cuprite
  • Управление браузером
  • Запуск теста в ограниченной среде
  • Cuprite API

...читайте в статье на нашем сайте.

Репозиторий проекта и инструкции к инсталляции на Github.

Вот на практике я столкнулся с несколькими вопросами по БЭМ и, хотя, я пересмотрел, наверное, все БЭМ-митапы и многие другие видео по БЭМУ, для меня ответы на, казалось, такие очевидные вопросы остались не совсем очевидными.

Допустим, у меня есть такая структура:

...
<body>

<header class="header">
  <span class="header__logo">LOGO</span>
</header>

<h1>Its home page</h1>

<div class="some-block">
  <p class="some-block__text">Some stuff</p>
</div>

<div class="some-block">
  <p class="some-block__text">Some another stuff</p>
</div>

</body>
</html>

И CSS:

.header {
  background-color: orangered;
}

.some-block {
  background-color: orange;
}

.some-block__text {
  margin: 0;
}

Первый вопрос. Что если мне нужно для блока Header поставить margin-bottom: 10px? Так как это блок и я хочу его переиспользовать, то для него задать я не могу. В таких случаях идеально должны подойти миксы, те сделать Header элементом другого блока, НО какого?

...
.???__header {
  margin-bottom: 10px;
}

Второй вопрос. Вот у меня на этой странице есть 2 блока Some Block и для них мне нужно сделать margin: 15px, те мне опять же нужно сделать его элементом какого-то блока (какого и как я пойму из первого ответа) и опять же сделать:

...
.???__some-block (или?) {
  margin: 10px;
}

Но что если для второго такого-же блока мне нужно, чтобы правый внешний отступ был 20px: margin-right: 20px (и это исключительно особенность его расположения на этой страницы, как и внешние отступы по 10px, просто для второго такого-же блока правый отступ нужен в 20px).

Третий вопрос. Что если у меня появились еще 3 дополнительных страницы, например, About, Contacts и Policy на каждой из которых (КРОМЕ Contacts) у блока Header как и на странице Home margin-bottom: 10px, а на странице Contacts margin-bottom: 15px (это чисто дизайнерская особенность этой странице и этот отступ для блока Header в 15px зависит только от того, что он находится на странице Contacts).

Четвертый вопрос. На каждой странице, как в примере со страницей Home у меня есть заголовок (h1), который показывает на какой странице я нахожусь и стили которого я до этого момента оставлял базовыми, но вот теперь я решил задать, что на всех этих страницах он будет размером в 27px, те мне его нужно выделить в отдельный блок? Или же на каждой странице сделать его элементом какого-то другого абстрактного блока (какого я пойму из первого вопроса)?

И вот я выделил как-то этот заголовок, но что если на странице Home (что является особенностью этой страницы) этот заголовок имеет размер 30px и color: green? Что сделать в этом случае?

Решил начать изучать bem пользуясь enb. Попутно хочу научится применять sass. Пользовался в осномном этой статьей. Там они, к слову не создавали элементы, но писали стили элементов блоков прям в стилях блоках. И вот что получилось: Создаю блок и элемент к нему, даю им по scss:

bem create -l desktop.blocks -b some-block -T scss
bem create -l desktop.blocks -b some-block -m some-elem -T scss

Далее говорю sass следить за все делом в папке desktop.blocks что бы тот формировал css

sass --watch desktop.blocks/

И далее идет некоторая магия enb (я еще не добрался до этого, в документации немного неясно описывается принцип сборки бандлов) и формируется наш готовый бандл

desktop.bundles/index/index.css

Собственно вопрос. Делают ли так вообще? Sass бы заиграл более ярко, если бы я писал все стили елементов в блоках. Например:

.some-block {
   &__some-elem {
      /* Стили элемента */
   }
}

Но тогда зачем нужно отдельно создавать элементы? Заранее спасибо

Всем привет!

Пытаюсь разобраться как правильно использовать БЭМ для заголовков и пока не могу найти правильное решение.

Поясню на примере: Есть блок title

.title {
    padding: 18px 0;
    font-size: 36px;
    font-weight: bold;
}

который используется так

<h1 class="title">Some text</h1>

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

  • Делать глобальный CSS-reset противоречит БЭМ (поскольку это глобальные стили и могут меняться от проекта к проекту)
  • Сбросить внешние отступы в самом блоке я не имею права (поскольку это внешняя стилизация)
  • Вариант который я сейчас вижу кажется мне очень костыльным
    <div class="title">
      <h2 class="title__text">Some text<h2>
    </div>
    
    .title__text {
      margin: 0;
      padding: 18px 0;
      font-size: 36px;
      font-weight: bold;
    }
    
    То есть сам блок это пустая обёртка а уже h1 или h2 - это элемент блока, который я могу стилизовать как мне нравится.

Очень хочу услышать ваше мнение поэтому поводу. Как правильно сделать это по БЭМ?

Анонимизация данных на лету на основе шаблонов

Как работать с персональными данными в тестовых средах?

В продакшене часто требуется хранить и использовать чувствительные данные, включая персональные данные (ПД). Разработчикам в работе на тестовых окружениях иногда бывают нужны данные, максимально приближенные к реальным, уже имеющимся в продукте. Несмотря на то, что в хранении пользовательских данных всегда применяются лучшие практики, такие регламенты и законы как ФЗ «О защите персональных данных», HIPAA, HITECH, CPRA или GDPR требуют, чтобы любые персональные данные хранились и использовались только там, где это необходимо и были защищены или анонимизированы при передаче.

Есть разные способы решения этой проблемы. Например, строгое разделение таблиц в базе данных: в каких-то хранятся персональные данные, в каких-то нет. Таблицы с ПД можно пропускать при экспорте или заменять их искусственными данными в системах разработки. Минус такого подхода — система должна быть изначально спроектирована с учётом такого разделения данных. К тому же искусственные данные хранятся достаточно близко с реальными прототипами, что может вызывать вопросы с точки зрения безопасности.

Другой способ — генерировать «чистый» дамп на стороне продакшена, в котором персональные данные скрыты или заменены несуществующими данными, похожими по формату на реальные. Разработчики могут сразу импортировать его, а риск утечки ПД при этом становится гораздо ниже.

Именно на таком подходе и основан Datanymizer.

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

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

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

Datanymizer: ваш новый помощник, сохраняющий конфиденциальность данных

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

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

Начало работы

Есть несколько способов установить pg_datanymizer. Выберите подходящий для вас.

Предварительно скомпилированный бинарный файл:

# Linux / macOS / Windows (MINGW and etc). Installs it into ./bin/ by default
$ curl -sSfL https://raw.githubusercontent.com/datanymizer/datanymizer/main/cli/pg_datanymizer/install.sh | sh -s

# Or more shorter way
$ curl -sSfL https://git.io/pg_datanymizer | sh -s

# Specify installation directory and version
$ curl -sSfL https://git.io/pg_datanymizer | sh -s -- -b usr/local/bin v0.1.0

# Alpine Linux (wget)
$ wget -q -O - https://git.io/pg_datanymizer | sh -s

Homebrew / Linuxbrew:

# Installs the latest stable release
$ brew install datanymizer/tap/pg_datanymizer

# Builds the latest version from the repository
$ brew install --HEAD datanymizer/tap/pg_datanymizer

Docker:

$ docker run --rm -v `pwd`:/app -w /app datanymizer/pg_datanymizer

README содержит пример конфигурации, которую можно использовать в качестве отправной точки.

Теперь вы можете вызвать Datanymizer для создания изменённого дампа ваших данных:

$ pg_datanymizer -f /tmp/dump.sql -c ./config.yml postgres://postgres:postgres@localhost/test_database

Эти команды создают новый дамп-файл /tmp/dump.sql с нативным SQL файлом для базы PostgreSQL. Мы можете импортировать фейковые данные из этого дампа в новую базу данных с помощью команды:

$ psql -Upostgres -d new_database < /tmp/dump.sql

Фильтры таблиц

Вы можете определить список таблиц, которые никогда не будут включаться в дамп. Например, для дампинга только public.markets и public.users data:

# config.yml
#...
filter:
  only:
    - public.markets
    - public.users

А для игнорирования этих таблиц при создании дампа из остальных:

# config.yml
#...
filter:
  except:
    - public.markets
    - public.users

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

Глобальные переменные

Вы можете определить глобальные переменные доступные из любого шаблона правил:

# config.yml
tables:
  users:
    bio:
      template:
        format: "User bio is {{var_a}}"
    age:
      template:
        format: {{_0 * global_multiplicator}}
#...
globals:
  var_a: Global variable 1
  global_multiplicator: 6

Встроенные правила

Datanymizer имеет встроенную поддержку («правила») для определенных типов значений, а также pipeline, позволяющий генерировать значения, применяя цепочки существующих фильтров для одного поля. Другие фильтры также включают параметры email, ip, words, first_name, last_name, city, phone, capitalize, template, digit, random_number, password, datetime и другие.

Ограничения уникальности

Уникальность поддерживается правилами email, ip, phone, random_number.

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

Вы можете менять количество попыток параметром try_count. Это опциональное поле, количество по умолчанию зависит от правила.

Планы на будущее

Вот какие функции мы хотим добавить в следующих обновлениях:

Pre-filtering: например, если необходимо выдавливать не всех пользователей, а тех, которые соответствуют определенным критериям (например, 100 пользователей, в возрасте 27 лет и старше, по имени Александр), с поддержкой произвольных SQL-запросов для фильтрации. Генерация данных: если вам нужно не анонимизировать существующие данные, а генерировать синтетические, основанные на определенных правилах. Поддержка других RDBMS: сейчас Datanymizer поддерживает только базы PostgreSQL, но в будущем добавится mySQL и MariaDB. Присоединяйтесь к разработке Datanymizer и предлагайте свои идеи!

Допустим, в моем проекте есть 2 уровня переопределения: "lib" и "project". На обоих уровнях присутствуют технологии "js" и "helper.js". Мне нужно, чтобы в итоговую сборку попали файлы "js" и "helper.js" из "project", и только "helper.js" из "lib". Т.е. что-то вроде этого:

const src = require('gulp-bem-src');

src(
    ['lib', 'project']
    [{ block: 'button' }],
    'js',
    {
        config: {
            'lib': {
                scheme: 'nested',
                techMap: ['helper.js']
            }
            'project': {
                scheme: 'nested',
                techMap: ['js', 'helper.js']
            }
        }
    }
)

Можно ли такое реализовать в gulp? В документации ничего такого не нашел, даже в методологии такие кейсы не описываются. Есть, конечно, gulp-merge и другие способы объединить потоки в gulp, но они будут замедлять сборку, т.к. придется заново вызывать gulp-bem-src, он будет заново разрешать зависимости т.д..

Здравствуйте. Использую бэм уже продолжительное время, но до сих пор иногда оказываюсь просто в растерянности в некоторых ситуациях Есть 2 кейса:

1. Первый кейс. У нас есть блок .contacts, который используется в header, footer и на странице контакты

.contacts
    .contacts__item
        .contacts__link

Во всех 3-х случаях его элементы выглядят и позиционируются немного по разному. Для позиционирования я делаю микс

.contacts.header__contacts
    .contacts__item
        .contacts__link

Но встает вопрос, как стилизовать элементы: Давать миксы header__item и header__link не вариант, т.к. в хэдере могут уже существовать эти классы вне контекста .contacts

1) Можно создать еще один пустой микс класс

.contacts.header__contacts.header-contacts
    .contacts__item.header-contacts__item
        .contacts__link.header-contacts__link

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

2) Можно делать кучу модификаторов для каждого элемента в отдельности, но тогда страшно представить сколько в проекте будет модификаторов, большинство из которых будет использоваться только 1 раз.

3) Можно сделать модификатор для блока и стилизовать каскадом

.contacts.contacts--theme--header.header__contacts
    .contacts__item
        .contacts__link

.contacts--theme--header .contacts__link {
}

Это вроде как противоречит идеям бэм, но мне кажется наиболее удачным решением.

2. Второй кейс. У нас есть базовый блок карточки

.card
   .card__img
   .card__inner
      .card__title
      .card__content
   .card__btn

Допустим она используется в каталоге. Но так же на странице с портфолио, но выглядит немного иначе. Создавать пустой микс класс .portfolio-card мне кажется плохой практикой, т.к. мы привязываемся к контексту. А что если эта модифицированная карточка будет еще на какой-то странице? Тогда само слово portfolio уже будет ни к селу ни к городу. Микс portfolio__img, portfolio__inner и т.д. тоже не жизнеспособны, т.к. нам нужно менять элементы именно в контексте карточки.

Я пришел к тому, что лучше всего будет давать карточкам абстрактные модификаторы

.card.card--type--1
   .card__img
   .card__inner
      .card__title
      .card__content
   .card__btn

.card--type--1 .card__img{
}

И стилизовать каскадом. Это дает нам полную модульность и свободу. Мы можем использовать модифицированные карточки где угодно в проекте. Более того, можно комбинировать модифицированные карточки с модификаторами элементов как угодно, например:

.card.card--type--1
   .card__img.card__img--hover--green
   .card__inner.card__inner--color--red
      .card__title
      .card__content
   .card__btn

.card--type--1 .card__img{
}

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

Был бы очень рад услышать аргументированную критику и ваши мысли на этот счет.

DEL

Здравствуйте. Есть блок product-card использующийся в каталоге и в слайдере на разных страницах. Имеет структуру

                        .card-add-product
                            .card-add-product__index 
                            .card-add-product__inner
                              .card-add-product__title
                              .card-add-product__descr
                            .card-add-product__thumb
                               img.form-group__img(src= obj.img)

Но в слайдере, мне нужно его немного изменить. Ограничить высоту, дать немного другие паддинги для .card-add-product__inner, изменить максимальные размеры изображения и т.п.

Я делаю это миксом через блок product-slider

                                 .product-slider__card.card-add-product
                                    .card-add-product__index
                                    .product-slider__inner.card-add-product__inner
                                        .card-add-product__title
                                        .product-slider__descr.card-add-product__descr
                                    .product-slider__thumb.card-add-product__thumb
                                        img.form-group__img(src= obj.img)

Так же можно было бы сделать модификаторы. И вроде как это соответствует БЭМ. Но давайте возьмем ситуацию, когда пройдет достаточно много времени и структура забудется либо проект будет поддерживать другой человек, который может быть незнаком с БЭМ. Ему нужно будет изменить цвет фона в карточке каталога. Он зайдет, посмотрит структуру и напишет в css.

.card-add-product {
  background: red;
}

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

.product-slider__card {
background: white;
}

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

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

В bemhtml, правила replace и wrap при любых значениях что-то делают. Например, для значений null, undefined, true и false, в результате будут просто пустые строки. Вопрос в следующем: каким образом можно переопределить данные правила так, чтобы они не применялись в принципе?

Вот пример:

block('test')(
    {
        replace: '...'
    },
    mod('test-mod')({
        // Не убирает предыдущий replace, а меняет его на пустую строку
        replace: undefined
    })
);
// Будет пустая строка
{
    block: 'test',
    mods: {test-mod: true}
}

Допустим, есть нескольких однотипных секций.

section.header

section.about

section.footer

В каждой секции есть блоки с одинаковым видом(стили), т.е.

<section class="header">
   <div class="header__title">Заголовок</div>
   <div class="header__subtitle">Подзаголовок</div>
   <div class="header__text">Основой текст. Основой текст. Основой текст. Основой текст.</div>
   <div class="header__btn><a class="header__link" href="#">Ссылка</a></div>
</section>

Раз он(стиль) повторяется, можно ли(правильно ли, с точки зрения БЭМ) сделать такую модификацию?

  1. Сделать микс с header, т.е. header fortext
  2. Вместо элементов сделать модификаторы
<section class="header fortext">
   <div class="fortext_title">Заголовок</div>
   <div class="fortext_subtitle">Подзаголовок</div>
   <div class="fortext_text">Основой текст. Основой текст. Основой текст. Основой текст.</div>
   <div class="fortext_btn"><a class="header__link" href="#">Ссылка</a></div>
</section>

Чтобы fortext... применять для др. секций

Код правильный, с точки зрения БЭМ ?? Или может лучше, как-то по другому?

<div class="reg">
  <button class="reg__btn reg__btn_close">Закрыть</button>
  <button class="reg__btn reg__btn_reg">Регистрация</button>
  <button class="reg__btn reg__btn_login">Вход</button>
</div>
.reg {}
.reg__btn {
  border: 0px;
}
.reg__btn_close {
  position: absolute;
  top: 0px;
  right: 0px;
  background-image: url(images/icon_close.png);
}
.reg__btn_reg {
  background-color: red;
  background-image: url(images/icon_reg.png);

}
.reg__btn_login {
  border: 1px solid black;
  background-color: green;
  background-image: url(images/icon_login.png);
}

Или кнопки с значительными изменениями лучше обозначать отдельным элементом, например: reg__close-btn?

Задача

У меня есть следующий bemhtml-шаблон на блок button:

{
    tag: 'button',
    content: (node, ctx) => ctx.icon ? [
        {
            elem: 'icon',
            url: ctx.icon
        },
        ctx.text ? {
            elem: 'text',
            content: ctx.text
        } : null
    ] : ctx.text || ctx.content
}

Здесь есть несколько вариантов генерации content. Также, есть блок form, у которого есть элемент send. Тело его шаблона выглядит следующим образом:

{
    tag: 'button',
    mix: {
        block: 'button',
        mods: {style: 'border', effect: 'invert'}
    }
}

По сути, мне нужно иметь возможность написать в bemjson что-то вроде этого:

{
    block: 'form',
    content: [
        {
            elem: 'send',
            icon: 'icon.svg',
            text: 'Submit'
        }
    ]
}

И я ожидаю результат:

<form class="form">
    <button class="form__send button button_style_border button_effect_invert">
        <svg class="button__icon" src="icon.svg"></svg>
        <span class="button__text">Submit</span>
    </button>
</form>

Что не является решением

Т.к. предикат на блок не срабатывает, находясь внутри микса, то никакой content не будет сгенерирован на основе icon и text. Предположим, я мог бы написать что-то вроде этого:

{
    block: 'form',
    content: [
        {
            block: 'button',
            mods: {style: 'border', effect: 'invert'},
            mix: {
                block: 'form',
                elem: 'send'
            },
            icon: 'icon.svg',
            text: 'Submit'
        }
    ]
}

Однако, реализация элемента form__send может изменится, и там могут быть совершенно другие модификаторы для button. Мне придется менять это везде в bemjson. По той же причине я не могу скопипастить реализацию content для button в form__send: реализация блока button может измениться.

В итоге

В идеале, мне нужно как-то задействовать поведение и button, и form__send в form__send. Т.к. через миксы это дело не работает, то я не знаю, что делать.

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

Добрый день. Добавляю к блоку header элемент inner в bemhtml

block('header')(
    tag()('header'),
    content()(function() {
        return {
            elem: 'inner',
            content: this.ctx.content
        };
    })
);

Указываю для этого элемента стили в

header/__inner/header__inner.css

При сборке вся разметка на месте

Однако, стили ни в enb, ни в gulp для этого элемента не собираются. Если же элемент прописать в bemjson, всё ок.

Как быть?

Приветствую всех! Использую упрощенную схему организации файловой структуры Flat. Как я понял, при использовании данной схемы, создается для каждого блока своя директория при этом стили и скрипты всех элементов и модификаторов хранятся в одно файле.

Блок:

<input class="input input_type_seach">

Схема файловой структуры:

common.blocks
--input
----input.css ( Содержание файла: .input {} .input_type_seach{} )
----input.js

Как правильно добавить этому блоку иконку?

<input class="input input_type_seach input_icon_user">

Схема файловой структуры:

common.blocks
--input
----input.css ( Содержание файла: .input {} .input_type_seach{} .input_icon_user{} )
----input.js
----input_icon_user.png

Так ли это работает?

Весь блок:

<div class="goods-items">
      <div class="goods-items__leftside">
             <div class="goods-items__item goods-items__item-first">
                <img class="goods-items__img" src="img/item1.png" alt="">
                 <span class="goods-items__price"><sup class="goods-items__money">£</sup>60</span>
                 <div class="goods-items__hidden">
                 <div class="goods-items__hidden-title">Womens burnt orange casual tee <span class="good-items__hidden-price"><sup class="goods-items__money">£</sup>29.99</span></div>
                 <div class="goods-items__hidden-desc">Classic casual t-shirt for women on the move. 100% cotton. </div>
                <div class="goods-items__hidden-icons">
                   <i class="goods-items__hidden-icon fa fa-shopping-cart"></i>
                   <i class="goods-items__hidden-icon fa fa-heart" aria-hidden="true"></i>
                   <i class="goods-items__hidden-icon fa fa-arrow-up" aria-hidden="true"></i>
                </div>
                <i class="goods-items__hidden-info fa fa-info-circle"></i>
                         =========Тут блок кода, написанный ниже======       
       </div>
    </div>
                       ....
</div>
<div class="goods-items__hidden">
   <div class="goods-items__hidden-preview">
       <div class="goods-items__hidden-preview-item"></div>
   </div>
</div>

То есть внутри блока goods-items находятся элементы hidden, hidden-preview и hidden-preview-item.

И правильное ли у меня наименование по БЭМ вообще? если нет, то укажите, пожалуйста, на ошибки

Проблема

Предположим, у меня есть следующий html:

<header class="header header_main">
    <button class="header__button button">
        <svg class="button__icon">
            <!-- SVG contents -->
        </svg>
        <span class="button__text">Button</span>
    </button>
</header>

И я хочу изменить элемент button__text у header__button. Предположим, изменить font-size. Я не уверен, но вроде вот так:

.header__button .button__text {
    font-size: 20px;
}

...делать нельзя. Потому что элемент button__text - часть внутренней реализации блока button. Поэтому, следующее что приходит в голову, просто сделать модификатор для button, что-то вроде этого:

.button_big-font .button__text {
    font-size: 20px;
}

Вроде все ок, добавляем модификатор, наслаждаемся. Но появляется следующего рода задача: нужно скрыть текст кнопок в шапке на мобильных устройствах. Вроде реализуется просто (конкретно в моем случае нужен именно display: none):

@media screen and (max-width: 575px) {
    .button_big-font .button__text {
        display: none;
    }
}

Вот только я могу применять модификатор big-font еще где-то вне header. И там я не хочу скрывать текст. Создавать модификатор, который можно применить только в определенном контексте (т.е. big-font только для header__button), тоже как-то не очень.

Попытки решения

Пробовал использовать css-переменные. Что-то вроде:

.button__text {
    display: var(--button_text-display, inline);
}
@media screen and (max-width: 575px) {
    .header__button {
        --button_text-display: none;
    }
}

Но все-таки скрытие текста - это вопрос внутренней реализации блока button. Там может использоваться как display: none, так и visibility: hidden, или вообще font-size: 0. А здесь я не только намертво вбиваю значение none, которое может использоваться только для display, но и позволяю применить другие значения, вроде flex, что не допустимо.

Также пробовал использовать правила @extend в sass. Но во-первых, они работают только в текущей области @media, а альтернативные решения плодят много css-кода на выходе. Во-вторых, @extend'ы чего-либо, относящегося к другому блоку, несколько ломают всю модульность.

Собственно вопрос

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

Здравствуйте.

Хочу получить сборку bemhtml для браузера.

В консоли браузера это работает (https://bem.github.io/bem-xjst/):

var bemhtml = BEMHTML();

var templates = bemhtml.compile(() => {
    block('text')({ tag: 'span' });
});

var bemjson = [
    { block: 'text', content: 'First' },
    { block: 'text', content: 'Second' }
];

var html = templates.apply(bemjson);

Как можно собрать для себя клиентский bemhtml из https://github.com/bem/bem-xjst/tree/master/lib?

Помогите пожалуйста разобрать что это значит - Имя блока задает пространство имен, которое гарантирует зависимость элементов от блока (blockelem). Разве зависимость элементов от блока гарантирует не их вложенность?) Что такое пространство имён? Если в блок вложить блок это он станет элементом? Если нет, почему в скобочках написано blockelem, а не block-elem? Извиняюсь за тупизну, слишком сложно для меня написано

Всем добрый день!

Есть такой кейс:

<!-- Тема «default» -->
<button class="button button_theme_default">
  <div class="button__text">Отправить</div>
</button>

<!-- Тема «outline» -->
<button class="button button_theme_outline">
  <div class="button__text">Отправить</div>
</button>

Так же есть, например, модификатор button_size_small который меняет размер button__text. Проблема/вопрос заключается в том, что есть необходимость при разных значениях модификатора button_theme_{name} менять поведение модификатора button_size_small, другими словами их связать. Итого при default и размере small хочется у button__text размер, например, 12px, а при outline и размере small хочется у button__text размер 14px.

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

  1. переименовать блок, например, вместо buttonbutton-outline.
  2. связывать модификаторы .button_theme_outline.button_size_small.
  3. добавить размер к названию темы, например, .button_theme_outline-small.

Более привлекательным (для меня) является 2-ой вариант. Но какой путь более правильный по БЭМ?

Спасибо!

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

У меня есть независимый(как мне казалось) блок .container, который выполняет свою функцию - ограничивает контент по ширине и добавляет padding . Я в него заворачиваю нужные мне блоки. И всё бы хорошо, пока я не решил сделать меню, которое может быть как sticky, так и мобильным.

Грубо говоря элементы так выглядят:

nav.mobile-sticky-menu
   .container.container--full-width
        ul.mobile-sticky-menu__list
                    ul.mobile-sticky-menu__list-item
                    ul.mobile-sticky-menu__list-item
                    ul.mobile-sticky-menu__list-item

При разных условиях(ширина окна, позиция скролла) добавляются разные модификаторы - --mobile, --sticky, и соот-но меню либо прилеплено к верху при скролле, либо через кнопку открывается справа/слева - мобильное.

Условия.

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

В состоянии mobile - мне не нужен мой контейнер, лишние паддинги.

.

.

Я понимаю, что я скорее всего где-то сильно косячу и полнейший нуб в БЭМ, но помогите понять как в таком случае правильно связать логически блок .container и блок .mobile_sticky-menu, чтобы сохранились условия выше.

Хочу сделать один из элементов списка активным. Активность подразумевает изменение цвета шрифта, фона, границ для вложенных элементов. Как это правильно сделать в БЭМ?

Пример вёрстки без БЭМ:

  <div class="item active">
    <div class="square"></div>
    <div class="text">Step 1</div>
  </div>
  <div class="item">
    <div class="square"></div>
    <div class="text">Step 2</div>
  </div>
  .item .text {
    color: gray;
  }
  .item .square {
    border: 1px solid gray;
  }
  .item.active .text {
    color: red;
  }
  .item.active .square {
    border-color: red;
  }

Реализация с БЭМ

  <div class="item">
    <div class="item__square item__square_active"></div>
    <div class="item__text item__text_active">Step 1</div>
  </div>
  <div class="item">
    <div class="item__square"></div>
    <div class="item__text">Step 1</div>
  </div>
  .item__text {
    color: gray;
  }
  .item__square {
    border: 1px solid gray;
  }
  .item__text_active {
    color: red;
  }
  .item__square_active {
    border-color: red;
  }

Так это делается в БЭМ или есть варианты? Такой вариант не удобно использовать.

Будьте добры, подскажите какой плагин стоит использовать для gulp, чтоб собирать БЭМ проекты? Желательно с документацией, тк новичок во всем этом :)

Подскажите каким инструментом можно преобразовать bemtree в css? Использую VSCode bem-express