2005 год... Классам блоков мы добавили префиксы (b-, c-, g-), чтобы отличать их от внутренних классов...
Исторически они появились в переходный период для того, чтобы отличать новый код, написаный по БЭМ, от старого. Со временем мы от них отказались.https://ru.bem.info/forum/158/ и https://ru.bem.info/forum/806/
Иногда к именам блоков могут добавляться различные префиксы.
Часто слышу, как разработчики говорят «БЭМ не нужен, ведь есть CSS-модули». Это не так.
Корень этого заблуждения кроется в том, что люди воспринимают БЭМ как CSS-методологию. На самом деле БЭМ это набор универсальных принципов, которые можно применять независимо от используемых технологий, будь то CSS, Sass, HTML, JavaScript или React. БЭМ решает множество задач, в число которых входят именование CSS-классов, подход к разделению интерфейса на независимые части и изоляция стилей для этих независимых частей.
CSS-модули это инструмент, который решает только проблему изоляции стилей. Все остальные проблемы остаются нерешёнными: вам всё ещё нужны какие-то правила для разделения интерфейса на независимые части и всё ещё нужно придумывать названия классов. Поэтому CSS-модули можно и нужно применять вместе с БЭМом.
Эволюция выглядит так:/* Классический БЭМ с длинными именами классов для обеспечения изоляции */ .shop-cart-button {} .shop-cart-button_size_small {} .shop-cart-button_size_large {} /* CSS-модули с неограниченной свободой творчества в именах классов */ .button {} .small {} .large {} /* или */ .button {} .is-small {} .is-large {} /* или */ .button {} .size-small {} .size-large {} /* БЭМ и CSS-модули */ .button {} .button_size_small {} .button_size_large {}
Сразу отвечу на вопрос «а чем плох пример с классами .button, .small и .large?». Он плох тем, что классы .small и .large сами по себе не несут информации о том, к чему они относятся. Нельзя понять, стилизуют ли они отдельный элемент или описывают состояние существующего элемента. Также такие названия классов рано или поздно снова приведут вас к проблеме уникальности имён. Например, вы пишете стили для модального окна. Вам нужно стилизовать полупрозрачный оверлей поверх страницы и само модальное окно. Оба этих элемента могут быть в двух состояниях: виден или скрыт. Кажется, что класс .visible отлично подходит, но проблема в том, что для оверлея и для окна этот класс должен содержать разные стили. Можно придумать костыль в виде селекторов .overlay.visible и .window.visible, но это именно костыль, потому что вы увеличиваете специфичность. С БЭМом всё просто и без ненужного роста специфичности: .overlay_visible и .window_visible.
...стилизовать немножко иначе...
git clone git://github.com/CultOfOpenSource/bem-zurb-foundation.git --depth 1 bem-zf-project
cd bem-zf-project
npm install
gulp build
phpstorm .
C:\projects\project
, проблема уйдет. site:css-tricks.com bem
site:csswizardry.com bem
site:smashingmagazine.com bem
page
.deps.js:[{
shouldDeps : [
{
elems : ['wrapper']
}
]
}]
.page // определяет свой внутренний мир и расположение своих элементов
.page__header // определяем внутренние отступы
.logo // ничего не знает о своем положении оно определяется в page__header
.page__menu
.menu // вполне самостоятельная переиспользуемая сущность
.page__footer
.logo_small // модификация знания про размер
.menu_small // может иметь различные вариации (модификаторы)
page__footer
и page__header
могут быть одним элементом page__section
для которого реализованы модификации page__section_header
и page__section_footer
... хотя на этом возможности не заканчиваются, еще может быть так page__section_type_header
и page__section_type_footer
.2005 год... Классам блоков мы добавили префиксы (b-, c-, g-), чтобы отличать их от внутренних классов...
Исторически они появились в переходный период для того, чтобы отличать новый код, написаный по БЭМ, от старого. Со временем мы от них отказались.https://ru.bem.info/forum/158/ и https://ru.bem.info/forum/806/
Иногда к именам блоков могут добавляться различные префиксы.
<div class="myBlock i-bem" data-bem='{"myBlock":{"param": "val"}}'>
...
</div>
modules.define('myBlock', ['i-bem-dom'], function (provide, bemDom) {
provide(bemDom.declBlock(this.name, /* методы экземпляра */ {
onSetMod: {
'js': {
'inited': function () {
this.domElem[0].innerHTML = this.__self.parseParams(this.params);
}
}
}
}, /* статические методы */ {
parseParams: function (params) {
return '<pre>' + JSON.stringify(params, null, ' ') + '</pre>';
}
}
));
});
header_logotype_link
и header_logotype_image
модификаторы блока («ключ-значение», если следовать Соглашение по именованию), а используются как самостоятельные единицы, их задача отражать модификацию именно блока: <section class="header header_logotype_image">
, но данном случае будет мало смысла.<!-- .header -->
<section class="header">
<div class="container">
<div class="header__top">
<div class="header__logotype">
<a href="#" class="link link_type_header">
<img src="_tmp/logotype.png" alt="Casino" class="image image_type_header">
</a>
</div>
</div>
</div>
</section>
<!-- /.header -->
.header {
&__top {}
&__logotype {}
}
.link {
&_type {
&_header {}
}
}
.image {
&_type {
&_header {}
}
}
<!-- .header -->
<section class="header">
<div class="container">
<div class="header__top">
<div class="header__logotype">
<a href="#" class="header__link link">
<img src="_tmp/logotype.png" alt="Casino" class="header__image image">
</a>
</div>
</div>
</div>
</section>
<!-- /.header -->
.header {
&__top {}
&__logotype {}
&__link {}
&__image {}
}
.link {}
.image {}
site:ru.bem.info "bem-xjst"
. ./node_modules/.bin/bem create -l desktop.blocks -b input -T css
Чтобы не указывать путь к исполняемому файлу...export PATH=./node_modules/.bin:$PATH
bem/project-stub/README.ru.md#Сборка-проекта
$PATH
для вашей ОС. .container--parallax {}
можно учитывать его наличие в реализации всех элементов блока .container--parallax .container__title {}
....каскад уместен, чтобы менять элементы в зависимости от состояния блока... Вкладывание элементов в элементы и другие тонкости
.container__title--parallax {}
мы сужаем область действия модификации только на элемент.{
tag : 'div',
attrs : {
id : 'anchor1',
name : 'BEM',
},
content : [
{
tag : 'div',
attrs : {
id : 'anchor2',
name : 'BEM 2',
},
content : 'BEM text'
},
]
}
<div id="anchor1" name="BEM">
<div id="anchor2" name="BEM 2">BEM text</div>
</div>
{
"content": "BEM Block!",
"title": "I am BEM"
}
block( 'someBlock' )(
def()( function () {
var data = this.ctx.data || {};
this.ctx.content = [
{ elem : 'title', content : data.title || 'Empty title' },
{ elem : 'content', content : data.content || 'Empty content' },
];
return applyNext();
} )
);