Всем привет. Благодаря репозиторию @tadatuta наткнулся на интересный плагин к PostCSS - rebem-css. Изначально показался он показался менее удобным, чем написание по-старинке.
// по-старинке
.object-item
&_status_bad
.object-item__extended
background: #000
// rebem-css
:block(object-item)
&:mod(status bad)
:block(object-item):elem(extended)
background: #000
Проблема 1
Подсветка синтаксиса при таком написание режет глаза...
Проблема 2
Код становится ещё длиннее... Утешает только то, что можно применять bem-naming
Проблема 3
Писали, что такой синтаксис ближе к BEMHTML. Но как по мне, он не дотягивает немного.
В итоге я решил сделать PR. В репозиторий rebem/css
, переписав практически весь плагин. Но т.к. на слитие нужно время, а мне он нужен уже сейчас, был сделан новый плагин с расширенным функционалом на основе rebem-css.
POBEMS поддерживает как синтаксис rebem-css, так и свой.
Решение 1-й проблемы
Добавлена возможность написания через кавычки
:block('object-item')
Решение 2-й проблемы
Добавлен контекст блока при объявлениях элементов и модификаторов. Теперь можно писать так
:block('block')
&:mod('mod val')
:elem('elem1')
background: #000
:elem('elem2'):mod('mod val')
width: 10px
:elem('elem3')
.block_mod_val .block__elem1
.block_mod_val .block__elem2_mod_val .block__elem3
Решение 3-й проблемы
Для объявления модификаторов добавил более привычный синтаксис через запятую :mod('mod', 'value')
:block('block')
&:mod('mod' -> 'val')
:elem('elem1')
background: #000
:elem('elem2'):mod('mod' -> 'val'):mod('mod2' -> 'val2')
width: 10px
.block_mod_val .block__elem1
.block_mod_val .block__elem2_mod_val.block__elem2_mod2_val2
Или в LESS стиле
:block('block') {
&:mod('mod', 'val') {
:elem('elem1') { }
:elem('elem2'):mod('mod', 'val'):mod('mod2', 'val2') {}
}
}
Что дальше...
Далее часть изменений отправлю в репозиторий rebem/css
, а в pobems буду добавлять более "горячие" нововведения. Репозиторий POBEMS
Мы у себя сошлись на
rebem-css
+postcss-nested
, что в итоге позволяет писать полностью валидныйsass
, так что с подсветкой все хорошо во всех редакторах (и даже на github):Меня
rebem-css
большего всего раздрожал постоянным дублированием объявления блока у элементов, когда элементы зависят от модификатора блока (или 2-х модификаторов). А в целом быстро на него перешёл. Код стал более понятным сходу.Обновил плагин, добавил поддержку разделителя '->' модификатор -> значение специально для stylus, т.к. он запятую не так как надо обрабатывает.
@belozyorcev а зачем тебе stylus? В postcss есть все необходимые плагины ;)
А может быть так? (замутить плагин поверх postCss sugarSs)
Давно так хочу сделать.
@awinogradov Куча кода уже была на stylus написана. Лень переписывать. В будущем буду от него уходить.
@a-x- мало знаком с sugarSS.
Плагин работает с такими строками, которые генерируются после: postCSS nested / Stylus / Less и т.д.:
Думаю ещё реализовать более "чистый" синтаксис:
@belozyorcev последний вариант выглядит симпатично. если будет нормально поддерживать в том числе всякие псевдоселекторы и вложенные селекторы, то 👍. ну и кавычки для имен сущностей нужно делать опциональными, не вижу смысла их писать в CSS.
@tadatuta они опциональны. И разделитель между mod - val тоже. Может использоваться либо
mod, val
, либоmod -> val
(для Stylus). Или же в стиле rebem-css - пробелmod val
upd. Мне кавычки добавляют более привычный синтаксис для моего восприятия и идентичности с BEMHTML.
По поводу псевдо-селекторов и вложенных селекторов уже на данной стадии всё работает. Эти моменты покрыты тестами.
pobems v0.3.1
полностью совместим сrebem-css v0.2.0
. https://github.com/belozyorcev/pobems/blob/master/test/lib/index.js#L46 https://github.com/belozyorcev/pobems/blob/master/test/lib/index.js#L53@a-x- SugarSS на сколько мне известно эмитирует Stylus (со слов Андрея Ситника). Значит можно попробовать так:
на выходе будут селекторы
А точно нельзя избавиться от всего этого шума
:block
:elem
и сделать плагин чтобы записывать так, как я выше показал?@a-x- можно, но это другая история. Целью данного плагина является изоляция от стиля именования блоков и добавление большей идентичности с BEMHTML, BEMTREE.
Начиная с версии 1.0.0 можно будет писать так
ну или так
или так
и это не предел )
Также думаю над нужностью/ненужностью короткого синтаксиса.
Может:
Или
Внесу таки 5 копеечек)
Мне кажется такой вариант оптимальным:
Пускай тут есть лишние ковычки, которые необязательны, но зато это легко переносить между шаблонами и стилями. Копипаст жив!)
А ещё можно моду css в bemhtml, чтобы само в файл эмитилось :)
@vithar при таком стиле могут возникнуть проблемы при парсинге, если в проекте используется что-то помимо БЭМ.
Ну для варианта, когда используется кто-то кроме БЭМ, ты уже сделал.
Я ищу наиболее лаконичный вариант писать именно BEM CSS код, чтобы он был максимально близок к валидному CSS, при этом легко читался.
Например так:
@awinogradov ни разу не сталкивался с необходимостью переносить селекторы из bemhtml в css и обратно.
@vithar сейчас я тебя больше понимаю.
@vithar думаю такое можно аккуратно реализовать , если скармливать плагину список блоков в проекте.
@vithar понятное дело) у тебя такой возможности не было) а теперь вот есть
Я так подумал... Синтаксис, который предложил @vithar будет прививать правильное написание стилей.
Если надо сдвинуть блок - сделай его элементом родителя и двигай в нём.
т.е. так правильней
чем
в итоге
объявление блока происходит только на 1-ом уровней, дальше - всё элементы.
Список блоков не надо скармливать, первый уровень — блоки.
@vithar да, я тебя просто не сразу понял.
.block1 .block2 иногда бывает надо, если надо достучаться до чего-то внутри, что ты не контролируешь в шаблонах, такой синтаксис нужен, может более вербозный, чем просто указание элеменов и других внутренностей блоков.
Можно, кстати, так
В смысле не пытаться вкладывать это в блок, а иметь на том же уровне. Но тут надо думать, как сделать аккуратно и нужно ли давать возможность достучаться до элементов другого блока (наверное нужно).
при склеивании селекторов получается
block1 item {}
и тут не понятно... Элемент это или блок.
Единственный вариант я вижу - это указание класса
block1 .block2
В общем про это можно думать отдельно и может даже сделать отдельный синтаксис, это же редкий кейс.