Open tenbits opened 7 years ago
Я так и не понял плюсов:
Разработка блока/компоненты не зависит от инструментария, как Css Modules, например
Не зависит от CSS Modules, но зависит от некоего кастомного преобразователя, который решает аналогичную задачу.
Все стили после сборки под селекторами с уникальной солью - нет коллизий Все изначальные классы в html остаются не тронуты - если вдруг нам нужно искать элементы из js, добавлять модификаторы, или определять новые стили по этим селекторам.
То ли нет коллизий и есть проблема с поиском, то ли нет проблемы с поиском, а значит есть вероятность коллизий как минимум в JS.
Все селекторы максимально плоские - хорошо для производительности Минимальная специфичность селекторов - хорошо для переопределения
Следование БЭМ-методологии само по себе сохраняет плоские селекторы и минимальную специфичность в рамках разумного. Кажется, что здесь нет нужды в дополнительных инструментах (особенно учитывая богатый арсенал уже существующих решений).
Не зависит от CSS Modules, но зависит от некоего кастомного преобразователя, который решает аналогичную задачу.
Разработка самой компоненты как раз не зависит от преобразователя, это обычный шаблон и привычные стили. Лишь во время сборки приложения стили выносятся в уникальные селекторы. Css Modules решает аналогичную проблему, но половинчатым путём. Они лишь генерируют уникальные селекторы, и дают нам json с полями. А мы уже в шаблонах через интерполяцию вставляем и комбинируем эти значения. А хотелось бы, что бы кто-то из существующего арсенала, взял шаблон компоненты, стили к нему, и преобразовал всё за меня, что бы эти стили не конфликтовали со стилями других компонент. Что-то знаете из существующих решений? То, как реализовали Scoped CSS у Angular или Veu отличный пример. Но мне кажется, что эта идея не до конца развита, и если в преобразователь "добавить" щепотку бэм-а, то будет очень даже хорошо)
Например, мне не нравиться, что они добавляют эти уникальные атрибуты к каждому html элементу. A имея такой селектор: header .title {}
, они генерируют такое в стилях: header[_ngcontent-bge-1] .title[_ngcontent-bge-1]
, а хотелось бы .myComponent__header_title
. Конечно же, их изначальная задача это симуляция scoped styles, но всё же.
То ли нет коллизий и есть проблема с поиском...
Именно что нет коллизий в стилях, а вот согласен, что проблемы с поиском могут быть. Но признаюсь, что у нас очень редко когда в компонентах по селекторам ищутся дом элементы (в основном всё завязано на bindings). Ну и в конце концов, идея лишь в какой-то степени добавить "полу-автоматический" бэм, а не заменить его.
Что-то знаете из существующих решений?
Мы описываем интерфейсы в BEMJSON, разметка генерируется с помощью шаблонов. Например:
{
block: 'my-component',
content: {
elem: 'elem1',
content: 'hello'
}
}
Шаблонизатор умеет из такого описания сгенерировать
<div class="my-component">
<div class="elem1">hello</div>
</div>
Попробовать можно здесь: http://bem.github.io/bem-xjst/
Нет никакой проблемы научить шаблонизатор по такому же описанию сгенерировать какие угодно классы.
Далее. Стили мы описываем с использованием плагина для PostCSS rebem-css:
:block(my-component):elem(elem1) {
}
Опять-таки здесь можно без проблем генерировать такие селекторы, какие хочется. В исходниках ничего менять не потребуется.
Остается JS, который мы пишем с помощью i-bem.js. Декларация компонентов выглядит так:
modules.define('my-component', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, {}));
});
При этом фреймворк предоставляет хелперы для поиска блоков и элементов, так что опять-таки, можно автоматизировать генерацию селекторов под капотом.
@tenbits А вам хочется побольше БЭМа в Ангуляр, или просто интересует, почему их подход менее гибкий?
Владимир (@tadatuta) спасибо за приведённые примеры. Согласен, БЭМ инструментарий отличная вещь, но это уже куда больше, чем просто стилизация дом элементов. В данном рассуждении я пытаюсь подойти больше с точи зрения "прогрессивного усложнения", где вначале "И был у нас простой шаблон и стили". БЭМ методология здесь отлично ложится - на эту простоту. Особенно хорошо, если у нас один большой html, с множеством блоков. Но у нас много маленьких компонент, и иногда бэм просто кажется избыточным. Иногда проще, если мы знаем что это атомарный блок, написать что-то подобное:
<import bem scoped href='foo.less' rel='stylesheet' />
<div class='foo'>
<h2>Foo</h2>
<ul>
<li class='item'> Hello
</ul>
</div>
.foo {
h2 {}
.item {}
}
Пример конечно высосан из пальца, да и импортируем мы по другому, но для примера это не столь важно. Так вот, такое стилизовать можно хоть в codepen-e. Ну а после сборки шаблон и стили компонента будут выглядеть как-то так.
<div class='foo_ABC'>
<h2 class='foo_ABC__h2'>Foo</h2>
<ul>
<li class='foo_ABC__item'> Hello
</ul>
</div>
.foo_ABC {}
.foo_ABC__h2 {}
.foo_ABC__item {}
И ещё раз, не обязательно вдаваться в такие крайности, можно и дальше придерживаться БЭМ методологии, но скажем с какими-то поправками, зная что у нас шаблоны разбиты на компоненты и что, в конце концов, когда собираются все view, никаких конфликтов имен не будет. Поэтому вот решил поинтересоваться, или кто-то думал уже о таких "поправках" и о таком подходе?
Алексей (@zxqfox) , нет, это мы для своих нужд решили внедрить некий модульных подход для стилизации элементов. Иногда становиться сложно придумывать уникальные имена блоков(. И вот присматриваемся, кто как к этому подходит. Пока что, почти реализовали выше изложенный подход. Потихоньку будем внедрять и тестировать, посмотрим как оно придется нам по душе.
Уважаемые бэмчане,
не сочтите за оффтоп, но хотелось бы услышать ваше мнение. Angular2 и Vue, например, имитируют scoped css через присваивание уникального атрибута всем тегам и добавление его же к селекторам в css. Возникла идея сделать эти трансформации приближенными к бэм методологии. Представьте, что у нашей компоненты шаблон и стили такие:
Тогда пропустив шаблон и стили через наш преобразователь получим следующее:
Принцип прост, по возможности заменить и сделать стили плоскими. Сохранить изначальный селектор Элементов и пройтись по шаблону Добавив новые имена классов. Изначально селекторы всегда вида: BLOCK(…modifiers) ELEMENT(…modifiers) … . Модификаторы мы не изменяем. В следующем примере селектор плоским сделать мы не можем, так как он зависит от состояния родителя:
Плюсы данного подхода:
Недостатки:
Дополнительно:
":host"
для его стилизации.Простите, что возможно сумбурно выразился, старался как можно компактнее подать идею. Есть ли у кого-то мысли по этому поводу?