Кон­цеп­ция быст­рой за­пи­си БЭМ (be­mto)

Та­кая идея!

Сна­ча­ла я хо­тел сде­лать ра­бо­та­ю­щий про­то­тип, но по­том по­ду­мал, что име­ет смысл, хотя бы для себя, за­пи­сать кон­цеп­цию «на бу­ма­ге».

Итак. Что та­кое БЭМ вы, на­де­юсь, уже зна­ете.

Сам по себе БЭМ та­ков, что име­на клас­сов для него раз­ду­ва­ют­ся, по­рой, до­нель­зя. При этом, идея вполне под­да­ёт­ся ав­то­ма­ти­за­ции, так что в клу­бе по ссыл­ке выше мож­но и об этом по­чи­тать. Од­на­ко, я все­гда лю­бил пи­сать код ру­ка­ми, лю­бил ста­тич­ный html, и ни­че­го не могу с со­бой по­де­лать. Ко­неч­но, со­всем плейн­тек­сто­вые фай­лы в наше вре­мя пи­сать до­воль­но стран­но, и я уже упо­ми­нал о том, что в по­след­нее вре­мя ис­поль­зую для ге­не­ра­ции ста­ти­ки фрейм­ворк nanoc. HAML, SASS, ав­то­об­нов­ле­ние стра­ниц при ре­ф­ре­ше в бра­у­зе­ре, всё такое.

И вот, —вне­зап­но! —пи­сать длин­ные кас­ка­ды клас­сов ру­ка­ми вы­хо­дит до­воль­но му­тор­но. Ка­кое-то вре­мя я пы­тал­ся ко­пать в сто­ро­ну ис­поль­зо­ва­ния под­шаб­ло­нов для бло­ков, ду­мал на тему ге­не­ра­ции SASS, но в ито­ге ни до чего тол­ком не до­шёл.

И, недав­но, в одну из ите­ра­ций мо­е­го мыс­лен­но­го про­цес­са на эту тему, я таки на­брёл на ни­точ­ку, ко­то­рая, ка­жет­ся, при­ве­дёт меня к вы­хо­ду из ла­би­рин­та хит­ро­спле­те­ний клас­сов для бло­ков-эле­мен­тов-мо­ди­фи­ка­то­ров и бес­ко­неч­ной их ко­пи­пас­ты и ав­то­ком­плита.

Ре­ше­ние до­воль­но про­стое, в са­мом ос­но­ва­нии её ле­жит прин­цип упро­ще­ния. Вот сра­зу, без лиш­них слов, идея в виде HTML-де­ре­ва, за­пи­сан­но­го CSS-се­лек­то­ра­ми, в фор­ма­те было-стало:

  1. .b-block­_­type­_­foo{:.nowrap} → .b-block.b-block­_­type­_­foo{:.nowrap}
  2. .b-block > .__el­e­ment{:.nowrap} → .b-block > .b-block­__el­e­ment{:.nowrap}
  3. .b-block > .__el > .__el{:.nowrap} → .b-block > .b-block­__el > .b-block­__el__el{:.nowrap}
  4. .b-block > .__el1 > .____el2{:.nowrap} → .b-block > .b-block­__el1 > .b-block­__el2{:.nowrap}
  5. .b-bl1 > .b-bl2_­foo > .__el + .____el_bar{:.nowrap} → .b-bl1 > .b-bl2.b-bl2_­foo > .b-bl2__el + .b-bl1__el.b-bl1__el_bar

Это для за­трав­ки. Если объ­яс­нять сло­ва­ми что про­ис­ходит:

  1. Что­бы про­пи­сать блок с мо­ди­фи­ка­то­ром не обя­за­тель­но пи­сать на­зва­ние клас­са по два раза по два раза, до­ста­точ­но на­пи­сать сра­зу мо­ди­фи­ка­тор. Мо­ди­фи­ка­тор без са­мо­го бло­ка ис­поль­зу­ет­ся при­мер­но ни­ко­гда.
  2. Эле­мен­ту бло­ка не нуж­но про­пи­сы­вать имя бло­ка.
  3. Мож­но со­зда­вать эле­мент для эле­мен­та.
  4. Если надо, мож­но по­смот­реть «на­верх» и про­пи­сать эле­мент для бло­ка выше по де­ре­ву (тут, кста­ти, надо за­ме­тить, что я этот пост я пишу в об­ще­при­ня­той БЭМ-но­та­ции, то­гда как сам ис­поль­зую для себя чуть иную —вме­сто «__» я пишу «-». Для меня это по­лу­ча­ет­ся чи­та­е­мее и с be­mto пи­сать в моей но­та­ции про­ще)
  5. Ну и со­че­та­ние все­го это­го дела выше.

Кар­ти­на на­чи­на­ет скла­ды­ваться?

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

Од­на­ко, се­лек­то­ра­ми дело не огра­ни­чи­ва­ет­ся. Всё то же са­мое мож­но сде­лать и для HAML (и, по идее, для лю­бо­го шаб­ло­ни­за­то­ра, сам я по­про­бую что-то сде­лать имен­но для HAML т.к. его лег­ко пар­сить, а я не про­грам­мист :)), в та­ком слу­чае запись

.b-bl1
  .b-bl2_­foo
    .__el
    .____el_bar

Бу­дет ин­тер­пре­ти­ро­вать­ся как

.b-bl1
  .b-bl2.b-bl2_­foo
    .b-bl2__el
    .b-bl1__el.b-bl1__el_bar

Ну а для SASS/​​SCSS мож­но на­пи­сать уже пост­про­цес­сор, тогда

.b-block {
    …
    ._foo {…}
    .__el­e­ment {
        …
        ._bar {…}
        }
    }

бу­дет рас­кры­вать­ся сас­сом сна­ча­ла в

.b-block {…}
.b-block ._foo {…}
.b-block .__el­e­ment {…}
.b-block .__el­e­ment ._bar {…}

что по­том про­стей­шей ре­гу­ляр­кой пре­об­ра­зу­ет­ся уже в то, что нам нужно:

.b-block {…}
.b-block­_­foo {…}
.b-block­__el­e­ment {…}
.b-block­__el­e­men­t_bar {…}

Ву­аля.

Кон­цеп­ция про­стая, ре­а­ли­за­ция не долж­на быть очень уж слож­ной, од­на­ко, сам я, если что-то и ре­а­ли­зую, то это бу­дет, ско­рее все­го, ре­а­ли­зо­ва­но крайне пло­хо. По­то­му, если вдруг кто-то за­го­рит­ся иде­ей и сде­ла­ет что-то из того, что я опи­сал (до­пол­не­ние к зен-ко­дин­гу, пре­про­цес­сор для HAML и пост­про­цес­сор для SASS), или же ре­а­ли­зу­ет эту кон­цеп­цию для чего-то ещё (LESS, лю­бой дру­гой шаб­ло­ни­за­тор, что угод­но), —я буду толь­ко за.

И ещё: это пока толь­ко на­ча­ло. В вёрст­ке и, в част­но­сти, в БЭМ я вижу мно­го чего, что мож­но раз­ви­вать и улуч­шать, мно­го моих идей хо­ро­шо ло­жат­ся ря­дом с кон­цеп­ци­ей be­mto. Так что, на­по­сле­док, мо­же­те по­ду­мать во что, по моим мыс­лям, мо­жет пре­вра­тить­ся сле­ду­ющее:

.b-block­_­foo._bar>.__b-link_lol>.__el­e­ment._

Добав­лено:

  1. В по­след­ней вер­сии Zen Cod­ing были ре­а­ли­зо­ва­ны неко­то­рые ас­пек­ты be­mto.
  2. Я на­чал раз­ра­бот­ку be­mto —на­бо­ра мик­си­нов для Jade, поз­во­ля­ю­щую де­лать мно­гие вещи, до­ступ­ные в be­mto (пус­кай и чуть-чуть об­ход­ны­ми пу­тя­ми).