# Часто задаваемые вопросы

## Почему БЭМ?

* [В чем отличие БЭМ от OOCSS, AMCSS, SMACSS, SUITCSS?](#В-чем-отличие-БЭМ-от-oocss-amcss-smacss-suitcss)
* [В чем разница между БЭМ и Web Components?](#В-чем-разница-между-БЭМ-и-web-components)
* [В чем разница между БЭМ и Bootstrap?](#В-чем-разница-между-БЭМ-и-bootstrap)

## Блоки и элементы

* [В каком случае создавать блок, в каком — элемент?](#В-каком-случае-создавать-блок-в-каком--элемент)
* [Почему в БЭМ не рекомендуется создавать элементы элементов (block\__elem1\__elem2)?](#Почему-в-БЭМ-не-рекомендуется-создавать-элементы-элементов-block__elem1__elem2)
* [Зачем писать имя блока в именах модификаторов и элементов?](#Зачем-писать-имя-блока-в-именах-модификаторов-и-элементов)
* [Как сделать глобальные модификаторы для блоков?](#Как-сделать-глобальные-модификаторы-для-блоков)
* [Зачем создавать отдельные директории и файлы для каждого блока и технологии?](#Зачем-создавать-отдельные-директории-и-файлы-для-каждого-блока-и-технологии)

## JavaScript

* [Зачем использовать i-bem.js, если можно писать на jQuery?](#Зачем-использовать-i-bemjs-если-можно-писать-на-jquery)

## CSS

* [Почему нежелательно использовать вложенные селекторы?](#Почему-нежелательно-использовать-вложенные-селекторы)
* [Почему в БЭМ не рекомендуется использовать комбинированные селекторы для создания CSS-правил к модификатору?](#Почему-в-БЭМ-не-рекомендуется-использовать-комбинированные-селекторы-для-создания-css-правил-к-модификатору)
* [Можно ли объединять тег и класс в селекторе (например, button.button)?](#Можно-ли-объединять-тег-и-класс-в-селекторе-Например-buttonbutton)
* [Почему в БЭМ не используют пользовательские теги (custom tag) для блоков?](#Почему-в-БЭМ-не-используют-пользовательские-теги-custom-tags-для-блоков)
* [Почему нельзя делать общий сброс стилей (reset)?](#Почему-нельзя-делать-общий-сброс-стилей-reset)
* [Почему нельзя писать block_mod вместо block block_mod, если имя модификатора уже содержит всю информацию о блоке?](#Почему-нельзя-писать-block_mod-вместо-block-block_mod-если-имя-модификатора-уже-содержит-всю-информацию-о-блоке)
* [Почему нельзя указывать название CSS-свойства в имени модификатора: .block\__element\_border-color\_grey?](#Почему-нельзя-указывать-название-css-свойства-в-имени-модификатора-block__element_border-color_grey)


**Не нашли ответ?** — [Задайте вопрос команде на форуме](https://ru.bem.info/forum/)

## В чем отличие БЭМ от OOCSS, AMCSS, SMACSS, SUITCSS?

1. БЭМ работает не только с CSS, но и с JavaScript.
1. БЭМ больше схож с Web Components, чем с перечисленными решениями для CSS. ([В чем разница между БЭМ и Web Components?](#В-чем-разница-между-БЭМ-и-web-components))
1. БЭМ предоставляет комплексное решение по созданию архитектуры проекта и помогает организовать процессы разработки. Подробнее читайте в разделе [Применение методологии для решения задач веб-разработки](../method/solved-problems/solved-problems.ru.md).

>Подробнее о [методологии БЭМ](https://ru.bem.info/method/).

Можно использовать БЭМ только на уровне CSS. Для этого достаточно просто следовать [рекомендациям методологии](../method/naming-convention/naming-convention.ru.md).

## В чем разница между БЭМ и Web Components?

Поддержка браузеров

* Web Components [не поддерживается](http://caniuse.com/#search=Web%20Components) в Safari, iOS Safari, Internet Explorer, Firefox.
* БЭМ работает во всех браузерах.

Инкапсуляция

* В Web Components реализована через Shadow DOM.
* В БЭМ — с помощью [элементов](../method/key-concepts/key-concepts.ru.md#Элемент) блока.

Работа шаблонов

* В Web Components шаблоны всегда выполняются в браузере. Это может потребовать дополнительных решений проблем с индексацией.
* В БЭМ генерация шаблона возможна на этапе разработки. Это позволяет отдавать готовый HTML. Шаблоны могут выполняться как в браузере, так и на сервере.


* Web Components использует императивный принцип — интерполяцию строк.
* БЭМ использует декларативный подход, который позволяет гибко управлять шаблонизацией и избегать повторений. Подробно о разнице между декларативным и императивным подходами смотрите в докладе [Сергея Бережного](https://ru.bem.info/authors/berezhnoy-sergey/) — [Шаблонизаторы](https://events.yandex.ru/lib/talks/553/).

Вместо импорта HTML — сборка

* Web Components использует импорт HTML (HTML Imports), который работает непосредственно в браузере. Для объединения HTML-файлов используется инструмент [Vulcanize](http://webcomponents.org/articles/introduction-to-html-imports/#aggregating-network-requests).
* БЭМ использует сборщики: [ENB](https://ru.bem.info/tools/bem/enb-bem/) или [bem-tools](https://ru.bem.info/tools/bem/bem-tools/).

Вместо Custom Elements — абстракция над DOM-деревом

* В Web Components используются Custom Elements. Такой подход позволяет разместить на одном DOM-узел только один компонент.
* В БЭМ существует понятие [БЭМ-дерева](../method/key-concepts/key-concepts.ru.md#БЭМ-дерево). БЭМ использует [миксы](../method/key-concepts/key-concepts.ru.md#Микс) — размещение нескольких БЭМ-сущностей на одном DOM-узле.

## В чем разница между БЭМ и Bootstrap?

В терминах БЭМ [Bootstrap](http://getbootstrap.com/) — это набор  сверстанных блоков. БЭМ — не библиотека элементов интерфейса, а методология, позволяющая:

* создавать архитектуру проекта;
* разрабатывать веб-приложения независимыми блоками;
* упрощать поддержку проектов.

Библиотека блоков, сделанных на БЭМ — [bem-components](https://ru.bem.info/libs/bem-components/). Существуют также и [другие](https://ru.bem.info/libs/) БЭМ-библиотеки.

## В каком случае создавать блок, в каком — элемент?

1. Если фрагмент кода может использоваться повторно и не зависит от реализации других компонентов страницы, необходимо создавать [блок](../method/key-concepts/key-concepts.ru.md#Блок).
1. Если фрагмент кода не может использоваться самостоятельно, без родительской сущности (блока), в большинстве случаев создается [элемент](../method/key-concepts/key-concepts.ru.md#Элемент).

Исключение составляют элементы, реализация которых для упрощения разработки требует разделения на более мелкие части — подэлементы. БЭМ-методология [не рекомендует создавать элементы элементов](#Почему-в-БЭМ-не-рекомендуется-создавать-элементы-элементов-block__elem1__elem2). В подобном случае вместо элемента необходимо создавать служебный блок.

## Почему в БЭМ не рекомендуется создавать элементы элементов (block\__elem1\__elem2)?

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

В методологии БЭМ вложенную структуру поддерживают только блоки (`block__elem`). Имя блока задает пространство имен, которое [гарантирует зависимость](../method/naming-convention/naming-convention.ru.md#Имя-элемента) элементов от блока.

Блок может иметь вложенную структуру элементов в DOM-дереве:

```html
<div class="block">
    <div class="block__elem1">
        <div class="block__elem2">
            <div class="block__elem3"></div>
        </div>
    </div>
</div>
```

Однако эта же структура блока в методологии БЭМ всегда будет представлена плоским списком элементов:

```css
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
```

Это позволяет изменять DOM-структуру блока без внесения правок в коде каждого отдельного элемента:

```html
<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>
    <div class="block__elem3"></div>
</div>
```

Структура блока меняется, а правила для элементов и их названия остаются прежними.

## Зачем писать имя блока в именах модификаторов и элементов?

Имя блока в именах [БЭМ-сущностей](../method/key-concepts/key-concepts.ru.md#БЭМ-сущность) обеспечивает:

* [Пространство имен](#Пространство-имен)
* [Миксы](#Миксы)
* [Поиск в коде](#Поиск-в-коде)

____________________________________________

**Важно!** Методология БЭМ [допускает выбор](../method/naming-convention/naming-convention.ru.md#Альтернативные-схемы-именования) удобной стратегии именования, но требует соблюдения консистентности в названиях. Так, например, все варианты верны: `context`, `ctx` или `c`, `attributes`, `attrs` или `as`. Необходимо выбрать один из них и использовать во всем проекте.
_____________________________________________

#### Пространство имен

Имя блока задает пространство имен и обеспечивает уникальность имен элементов и модификаторов. Это позволяет ограничить влияние элементов и модификаторов одного блока на реализацию другого.

#### Миксы

[Микс](../method/key-concepts/key-concepts.ru.md#Микс) — это совмещение разных БЭМ-сущностей на одном DOM-узле. При миксе модификатора имя блока указывает, к какому блоку применится модификатор. Если имя блока не указать, модификатор применится ко всем миксуемым БЭМ-сущностям.

Например, рассмотрим микс пункта меню (`menu__item`) и кнопки (`button`):

```html
<div class="menu__item button"></div>
```

Добавим модификатор `active` в сокращенной форме записи (без имени блока):

```html
<div class="menu__item button active"></div>
```

В таком виде HTML-разметка не дает понять, к чему относится модификатор: к пункту меню (`menu__item.active`) или к кнопке (`button.active`). Имя блока (`button_active`) явно указывает на БЭМ-сущность, к которой будет применен модификатор.

Также запись `<div class="block mod">` не дает понять, какие БЭМ-сущности используются в работе. Например, из записи `<div class="checkbox button">` нельзя однозначно определить, это микс модификатора и блока или микс двух блоков.

Полное имя модификатора `<div class="block block_mod">` показывает, о каких сущностях идет речь: `<div class="checkbox checkbox_button">`.

#### Поиск в коде

Явные и уникальные имена облегчают поиск необходимой сущности в коде и файловой системе.

Сравним результаты глобального поиска при отладке проекта. Найдем модификатор `active`. В сокращенном виде (`active`) в результаты поиска попадут все возможные комбинации и HTML-фрагменты, где встречается `active`. В записи, рекомендуемой методологией, само название уже будет содержать уточняющий параметр в виде имени блока (`button_active`). Так как имя модификатора уникально, в результаты поиска попадут только нужные фрагменты кода.

## Как сделать глобальные модификаторы для блоков?

В БЭМ отсутствует понятие глобальных модификаторов, так как модификатор всегда относится к одной конкретной [БЭМ-сущности](../method/key-concepts/key-concepts.ru.md#БЭМ-сущность).

Если требуется вынести CSS-свойство за пределы одного блока и применять его к разным БЭМ-сущностям в проекте, необходимо создавать отдельный блок, реализованный в технологии CSS.

БЭМ позволяет совмещать реализацию разных блоков с помощью [миксов](../method/key-concepts/key-concepts.ru.md#Микс):

```html
<div class="block1 block2"></div>
```

## Зачем создавать отдельные директории и файлы для каждого блока и технологии?

Файловая система БЭМ-проекта разделяется на вложенные директории и файлы для [удобства разработки и поддержки проекта](../method/filesystem/filesystem.ru.md#Реализация-блока-разделяется-на-отдельные-файлы).

Придерживаться [рекомендуемой структуры файловой системы](../method/filesystem/filesystem.ru.md#Организация-файловой-системы-БЭМ-проекта) не обязательно. Вы можете использовать любую альтернативную структуру проекта, соответствующую [принципам организации файловой системы БЭМ](../method/filesystem/filesystem.ru.md#Принципы-организации-файловой-системы-БЭМ-проекта), например:

**flex-схема**

* Блоку соответствует отдельная директория.
* Элементы и модификаторы реализованы в отдельных файлах.

```files
blocks/
  input/
      input_layout_horiz.css
      input_layout_vertical.css
      input__elem.css
      input.css
      input.js
  button/
```

* Блоку соответствует отдельная директория.
* Элементы и модификаторы реализованы в файлах блока.

```files
blocks/
  input/
      input.css
      input.js
  button/
```

* Директории для блоков не используются.
* Элементы и модификаторы реализованы в файлах блока.

```files
blocks/
  input.css
  input.js
  button.css
  button.js
```

**flat-схема**

* Директории для блоков не используются.
* Опциональные элеметы и модификаторы реализованы в отдельных файлах.

```files
blocks/
  input_type_search.js
  input_type_search.bemhtml
  input__box.bemhtml
  input.css
  input.js
  input.bemhtml
  button.css
  button.js
  button.bemhtml
  button.png
```

## Зачем использовать i-bem.js, если можно писать на jQuery?

[i-bem.js](https://ru.bem.info/technology/i-bem/) это специализированный фреймворк для разработки проектов на JavaScript в терминах блоков, элементов и модификаторв.

`i-bem.js` не предназначен для замены фреймворка общего назначения, такого как jQuery.

`i-bem.js` позволяет:

* разрабатывать веб-интерфейс в терминах блоков, элементов, модификаторов;
* интегрировать JavaScript-код с шаблонами и CSS-правилами в стиле БЭМ;
* описывать логику работы блока как набор состояний.

## Почему нежелательно использовать вложенные селекторы?

Ключевая идея БЭМ — независимость блоков. [Вложенные селекторы](http://htmlbook.ru/css/selector/descendant) увеличивают связанность кода и делают его повторное использование невозможным. Это противоречит принципам БЭМ.

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

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

```css
.nav_hovered .nav__link
{
    text-decoration: underline;
}
```
```css
.nav_theme_islands .nav__item
{
    line-height: 1.5;
}
```

## Почему в БЭМ не рекомендуется использовать комбинированные селекторы для создания CSS-правил к модификатору?

Комбинированные селекторы усложняют переопределение блока, так как имеют более высокую специфичность в CSS, чем одиночные. Специфичность комбинированного селектора для модификатора блока (`.block1.mod`) и для переопределенного блока (`.block2 .block1`) одинакова. Переопределение блока будет зависеть только от порядка объявления правил в декларации.

Рассмотрим пример:

```html
<div class="header">
  <button class="button active">
</div>
```
Правила модификатора `active` для кнопки записываются как комбинированный селектор `.button.active`. При переопределении кнопки с помощью родительского блока `header`, создается селектор `.header .button`. Специфичность обоих селекторов одинакова, значит применение CSS-правил определяется порядком их объявления в декларации.

Использование имени блока в названии модификатора обеспечивает более высокий приоритет CSS-правилам при переопределении блока.
Селектор `.header .button` всегда будет иметь приоритет выше, чем `.button_active`.

>[Причины использования имени блока в имени модификатора](#Зачем-писать-имя-блока-в-именах-модификаторов-и-элементов)

## Можно ли объединять тег и класс в селекторе? Например, button.button.

Совмещение тега и класса в селекторе повышает специфичность CSS-правил. При добавлении модификатора правила блока не смогут быть переопределены, так как специфичность селектора блока выше.

Рассмотрим пример:

```html
 <button class="button">
```

Записываем для него CSS-правила в селекторе `button.button`.

Добавим модификатор:

```html
 <button class="button button_active">
```

Cелектор `.button_active` не переопределит свойства блока, записанные как `button.button`, так как специфичность `button.button` выше. Для успешного переопределения селектор модификатора блока также должен быть скомбинирован с тегом `button.button_active`.

В результате развития проекта могут появится блоки с селекторами `input.button`, `span.button` и, например, `a.button`. В таком случае все модификаторы блока `button` и вложенные в него элементы потребуют четыре разные декларации для каждого случая.

## Почему в БЭМ не используют пользовательские теги (custom tags) для блоков?

>Блоки могут выражаться в HTML с помощью пользовательских тегов, к которым создаются CSS-правила. В таком случае классы можно будет использовать только для модификаторов: `<button class="mod"/>`.

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

* Невозможно использовать [миксы](../method/key-concepts/key-concepts.ru.md#Микс).
* Не любой блок можно выразить пользовательским тегом. Например, для всех ссылок необходим тег `<a>`, а для полей — `<input>`.

## Почему нельзя делать общий сброс стилей (reset)?

Блок — независимый компонент. На него не должны влиять CSS-правила, созданные для всей страницы. Это нарушает независимость блоков и затрудняет их повторное использование.

Общий сброс стилей по сути реализуется с помощью [глобальных CSS-правил](#Как-сделать-глобальные-модификаторы-для-блоков), которые в большинстве случаев пишутся к [селекторам на тег](#Почему-в-БЭМ-не-используют-пользовательские-теги-custom-tags-для-блоков), что нежелательно использовать в БЭМ-проекте.

Если сбросить стили все-таки необходимо, в БЭМ это делается в каждом блоке.

Рассмотрим пример. Если в проекте блоки меню и список выражены в HTML с помощью тега `<ul>`, значит каждый блок должен предоставлять сброс CSS для `<ul>`. Повторов в результирующем коде можно избежать с помощью CSS-оптимизатора.

Если в проекте не используется CSS-оптимизатор, который объединяет селекторы с одинаковым набором правил, можно применить CSS-препроцессор. Тогда для каждого нового блока можно делать сброс правил, [миксуя](../method/key-concepts/key-concepts.ru.md#Микс) чистый код. Например, в SASS это будет выглядеть так:

```css
.menu {
    @include reset-list;
}
.menu__item {
    @include reset-list-item;
}
...
.list {
    @include reset-list;
}
.list__item {
    @include reset-list-item;
}
```

Такой способ следует использовать только при отсутствии оптимизатора.

## Почему нельзя писать block\_mod вместо block block\_mod, если имя модификатора уже содержит всю информацию о блоке?

Совмещение нескольких модификаторов на одном и том же блоке (например, `<div class="block_theme_christmas block_size_big">`) приведет к дублированию кода, реализующего базовую функциональность (логику и стили) блока.

## Почему нельзя указывать название CSS-свойства в имени модификатора: .block\__element\_border-color\_grey?

* При изменении внешнего вида блока или элемента придется менять не только CSS-код, но и названия селекторов. Например, если цвет границы изменится с серого (`grey`) на красный (`red`), нужно будет изменить шаблоны и, вполне вероятно, JavaScript-код.
* При добавлении других свойств (фона, отступов), имя перестанет соответствовать содержанию модификатора.

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