Существует замечательная методика вёрстки БЭМ, продвигаемая Яндексом. Она подразумевает создание очень большого количества css-файлов с определённой структурой папок. Для крупных проектов это вполне оправдано, но для обычных корпоративных сайтов и интернет-магазинов гораздо удобней, когда все стили находятся в 1-3 css-файлах. Кроме того, сам фреймворк Yii навязывает свою структуру папок для расположения стилей.

Т.к. ygin склеивает css- и js-файлы, верстальщику бывает крайне не удобно работать. Эта проблема решается выключением склейки в файле /protected/config/local.php:

'clientScript' => array(
  'combineCss' => false,
  'combineJs' => false,
),

Существует основной файл стилей, применяемых на сайте: /themes/business/css/page.css

Имеется вспомогательный файл стилей, который помимо того, что подключается на внешней части сайта, также подключается в системе управления к редактору TinyMCE: /themes/business/css/content.css. Таким образом, существует возможность обеспечить одинаковае отображение текста на сайте и в системе управления.

Стили для отдельных модулей сайта находятся в папке assets соответствующих модулей. Для того, чтобы изменять эти стили необходимо выполнить процедуру переопределения файлов модуля. После переопределения стили для модуля Новостей, например, можно будет редактировать по следующему пути: /protected/modules/news/assets/news.css.

Адаптированный БЭМ

Учитывая все вышеописанные особенности движка, БЭМ в классическом виде у нас не применяется, тем не менее сохранена система блоков и элеменов, являющаяся наиболее полезной во всей этой методологии.

  1. Не используйте идентификаторы в селекторах
    Да, мы знаем, что идентификаторы в селекторах работают быстрее. Тем не менее, на практике заметить разницу в скорости рендеринга в большинстве случаев не возможно. С другой стороны, никогда не знаешь, в какой момент потребуется использовать уже существующие стили повторно на одной и той же странице. Селекторы с использованием только классов позволяют легко решить эту проблему.
  2. Не используйте классы бутстрапа в селекторах
    В случае, когда элементу требуется задать стили, лучше будет создать отдельный класс, нежели использовать существующие классы бутстрапа. Рассмотрим пример с кнопкой:
    <div class="b-miracle">
      <button class="btn">Кнопка</button>
    </div>
    

    Допустим, кнопке необходимо задать отступ слева. Неправильным является использование существующего класса бутстрапа: .b-miracle .btn {margin-left:10px}. Правильным будет создать новый дополнительный класс специально для этого элемента и выразить стили через него: .b-miracle .btn-miracle {margin-left:10px}

    Дело в том, что классы бутстрапа являются служебные и их в соответствии с изменениями бутстрапа существует вероятность изменения их стилей, а также их названий, как это было при переходе от бутстрапа 2 к бутстрапу 3. Для того, чтобы вёрстка сайта при такой миграции не пострадала, лучше предусмотрительно использовать свои классы вместо служебных.

  3. Элементов без блоков не должно быть
    В соответствии с правилами БЭМ, не должно быть ни одного элемента, класс которого выражался бы без блока, в котором он находтся. Соблюдение этого простого правила способно обеспечить минимум проблем, связанных с перекрыванием стилей одного блока другим. Рассмотрим пример такого элемента:
    <div class="b-miracle">
      <span class="date">12.10.2013</span>
    </div>
    <div class="b-wispa">
      <span class="date">12.10.2013</span>
    </div>
    

    В случае неправильного использования селектора элемента без его блока зачастую происходит ненарочное перекрывание .date {color:#f00} .date {color:#ff0}. Этого можно было бы избежать, если все элементы блоков выражаются через их блоки: .b-miracle .date {color:#f00} .b-wispa .date {color:#ff0}.

    Данная проблема особо актуальна для крупных проектов, над которыми работают несколько верстальщиков.

  4. Правильно выбирайте размер блока. Основной ошибкой начинающих верстальщиков на БЭМ является слишком подробное дробление кода на блоки. Буквально все стили пишутся в виде блоков, в результате получается ситуация, когда повторное использование стилей и кода практически невозможно. Например:
    <div class="b-miracle">
      <span class="b-date-a">12.10.2013</span>
    </div>
    <div class="b-wispa">
      <span class="b-date-b">12.10.2013</span>
    </div>
    

    На практике лучше всего делить блоки по функциональным признакам. Например, список новостей (.b-news-list) и его элементы: дата (.b-news-list .date), заголовок (.b-news-list .title), текст (.b-news-list .text). Виджет новостей (.b-news-widget) и его элементы: дата (.b-news-widget .date), заголовок (.b-news-widget .title), текст (.b-news-widget .text). Блоками могут выступать список Документов, виджет Поиска, шапка сайта, Баннеры и другие достаточно крупные функциональные элементы страницы. Но такие мелкие элементы как Дата, Заголовок, Краткий текст, Кнопка должны быть элементами и их стили должны выражаться через класс блока, в котором они находятся.

    Подробно и наглядно с картинками об этом можно прочитать в статье "Что такое БЭМ?"

В заключение приведу пример блока, написанного в соответствии применяемой нами методикой БЭМ:

<style>
.b-news-widget .item {margin:5px 0 5px 0; padding:0 0 10px 0; clear:left}
.b-news-widget .date {font:10px Verdana,Geneva,sans-serif; color:green}
.b-news-widget .text {font:12px "Trebuchet MS", Arial, Helvetica, sans-serif; margin:3px 0 0 0}
.b-news-widget .more {font:12px "Trebuchet MS", Arial, Helvetica, sans-serif; text-align:right; clear:left; display:none}
.b-news-widget h3 {font:14px/16px 'Trebuchet MS',Arial,sans-serif; margin:0}
.b-news-widget a:link, .b-news-widget a:visited {color:#ff0}
.b-news-widget a:hover {text-decoration:none}
.b-news-widget .rss {margin:0 0 0 10px}
.b-news-widget .rss img {vertical-align:baseline}
.b-news-widget .addYandex {position:relative; margin:0 0 0 5px; vertical-align:baseline}
.b-news-widget .addYandex img {clip: rect(60px, 428px, 76px, 400px); position:absolute; top:-57px; left:-400px; vertical-align:baseline}
.b-news-widget .photo {margin:6px 6px 0 0; float:left}
.b-news-widget .photo img {width:100px}
.b-news-widget .archive {margin:-5px 0 20px; clear:left}.b-vote-widget {margin-bottom:20px}
</style>
<div class="b-news-widget">
  <h2>Новости</h2>
  <div class="item">
    <div class="date">17.07.2011</div>
    <h3><a href="/news/11/">Сыктывкар перейдет на трехлетний бюджет</a></h3>
    <div class="photo">
      <a title="Сыктывкар перейдет на трехлетний бюджет" href="/news/11/"><img src="/content/news/11/BALLOON_1_list.jpg" alt="Сыктывкар перейдет на трехлетний бюджет"></a>
    </div>
    <div class="text">Бюджет Сыктывкара будет утверждаться сроком на три года, что соответствует стратегии социально-экономического развития муниципалитета до 2025 года. Соответствующий проект решения депутаты рассмотрели на заседании постоянных комиссий совета города вчера, 6 июля.</div>
    <div class="more"><a href="/news/11/">Полный текст</a> »</div>
  </div>
  <div class="item">
    <div class="date">17.07.2011</div>
    <h3><a href="/news/10/">Сыктывкарский пивзавод присоединился к обращению Союза российских пивоваров в адрес президента РФ</a></h3>
    <div class="text">ОАО "Сыктывкарский пивзавод" поддержал обращение Союза российских пивоваров в адрес президента РФ Дмитрия Медведева.</div>
    <div class="more"><a href="/news/10/">Полный текст</a> »</div>
  </div>
  <div class="item">
    <div class="date">17.07.2011</div>
    <h3><a href="/news/9/">На Монди СЛПК прошла ярмарка проектов "Премии Лесной академии Коми"</a></h3>
    <div class="text">12 июля на ОАО "Монди СЛПК" прошла первая ярмарка проектов на соискание премии Лесной академии Коми. В мероприятии приняли участие руководство предприятия, первый заместитель министра развития промышленности, транспорта и связи Александр Гибеж, мэр Сыктывкара Иван Поздеев, сотрудники и студенты учебных заведений республики и других регионов.</div>
    <div class="more"><a href="/news/9/">Полный текст</a> »</div>
  </div>
  <div class="item">
    <div class="date">17.07.2011</div>
    <h3><a href="/news/8/">СМН стали лучшими в Коми в номинации за сокращение производственного травматизма</a></h3>
    <div class="text">Республиканская трехсторонняя комиссия по регулированию социально-трудовых отношений подвела итоги республиканского конкурса "Организация высокой социальной эффективности".</div>
    <div class="more"><a href="/news/8/">Полный текст</a> »</div>
  </div>
  <div class="archive"><a href="/news/">Все новости  »</a></div>
</div>
12 октября 2013

Автор: Огнёв Иван

Комментарии (3)

Добавить комментарий
  • Знающий
    13.12.2013, 17:39:39

    Это не БЭМ батенька, это г**** какое то...
  • Разработчик
    13.12.2013, 17:42:48

    Во-первых, каскад используете. В БЭМе он переходит на плечи классов, описывающих этот каскад.
    Во-вторых, истекающее из первого, не правильные классы у вас:
    <div class="item">... чего итем то? меню-итем? ньюс-итем? должно быть:
    <div class="news-widget__item"> ну в общем вы поняли...
  • Иван
    13.12.2013, 18:34:17

    Спасибо, за конструктивную критику нашего подхода :) У нас действительно не классический БЭМ, а его упрошение.

    Специфика реализуемых нами проектов такова, что редко в блоке встречается несколько итемов разных типов, поэтому нет смысла усложнять имена классов массивными конструкциями типа news-widget__item.