18 декабря 2014 в 02:07

БЭМ с человеческим лицом и интеграция с backend

Верстка современных web-проектов – это сложно, долго и дорого. Казалось бы, с переходом IE на автоматические обновления, HTML5, окончанием поддержки Win XP все мы должны зажить в сказочной стране с пони и радугой. Почему легче не стало?

  • HTML5 и CSS3 подарили вебу возможность создавать UI, почти не уступающий по сложности и отзывчивости desktop-приложениям. Ничто не дается просто так, HTML, CSS и JS стало в разы больше. Раньше нам хватало трех файлов: styles.css, stupid-ie-must-die.css, scripts.js. Сейчас количество скриптов, стилей, загружаемых шрифтов, картинок измеряется десятками и сотнями. Появилась необходимость в минификации, ускорении рендеринга и организации всего этого барахла в файловой системе.
  • Сайты постепенно перестали быть набором связанных гипертекстовых страничек и стали web-приложениями. Если раньше для многих сайтов достаточно было сверстать «главную» и «внутреннюю» страницы, то сейчас все совсем не так просто. Количество дизайн макетов легко достигает десятков и сотен.
  • Мы все наслушались про лендинг-пейдж, a/b-тестирование и многократное увеличение конверсии за «просто-так». Оставим за бортом вопрос об эффективности этих методик. Дизайн начали переделывать часто – это факт. Известно, что внесение изменений и поддержка – гораздо дороже и сложнее, чем разработка.
  • Появились мобильные устройства и необходимость в адаптивном дизайне. Тестировать стало сложнее и дольше. Цикл исправления найденных при тестировании багов стал дольше. Тестирование UI почти не поддается автоматизации, с ростом функционала время на регрессионное тестирование неуклонно растет.
  • Усложнилась интеграция с backend-кодом, появилась необходимость делать это гораздо чаще.


Все это заставляет задуматься об оптимизации работы с фронтэндом.


Хочется:
  • Уменьшить время и количество интеграционных работ («натягивание» сверстанного макета на серверную технологию)
  • Повысить повторное использование html, css и js, уменьшить количество соответствующего кода
  • Снизить время на модификацию существующего кода
  • Уменьшить количество ошибок при модификации, особенно регрессии
  • Научиться создавать и верстать адаптивный дизайн эффективно



Самое простое решение – отказаться от серверной шаблонизации вовсе, перейти на REST-API и SPA


Плюсы


  • Этап интеграции исчезает вовсе
  • Бэк и фронт разделены, каждая команда более мобильна и им вообще не обязательно использовать общий набор инструментов
  • Фронтэндщику не нужно разворачивать серверный стек

Минусы


  • SEO
  • Необходимость в «толстом клиенте»
  • Неявное дублирование кода: ViewModel на клиенте и DTO на сервере


Минусы довольно серьезные. Какие варианты, если шаблоны на сервере?


Фронтедщик редактирует серверные шаблоны


Плюсы


  • Не надо «дергать» бэкэндщика

Минусы


  • Фронтэндщику нужно держать два набора инструментов и переключаться между ними
  • Фронтэндщику сложно использовать незнакомую технологию, всякие @using(Hml.BeginForm(//… и <?php $form->textbox(‘name’)
  • Фронтэндщик может «сломать» серверный код и не понять этого
  • Фронтэндщик не знает стандартов кодирования бэкэнд-команды
  • Фронтэндщику нужно разворачивать и конфигурировать все приложение в т.ч. БД и другие зависимости


Фронтэдщик редактирует свои шаблоны в чистом html без серверных вставок (возможно с препроцессорами) и передает бэкэндщику


Плюсы


  • Не нужно дублировать набор инстурментов, каждый занимается своим делом, в котором он специалист
  • Простота конфигурирования сред
  • Возможность параллельно верстать много абсолютно разных макетов силами разных подрядчиков

Минусы


  • Дублирование работы
  • Необходимость редактировать шаблон в двух местах
  • Мы никак не сократили затраты на интеграцию


Фронтэдщик использует серверный движок при верстке и самостоятельно выделяет лейауты, блоки и шаблоны


Плюсы


  • Затраты на интеграцию практически исчезают
  • На сервере и клиенте используется одинаковый набор инструментов и язык программирования (особенно этот подход привлекателен для node.js)
  • Требуется более тесное взаимодействие фронт и бэк-команд для согласования «нарезания» шаблонов и блоков

Минусы


  • Требуются инструменты, возможно, они уже существуют, возможно, — придется написать (для php и asp.net это делается за день-два)
  • Инструменты могут быть не совместимы с sass/less/stylus/другими любимыми препроцессорами
  • Более крутая кривая обучения для новых сотрудников
  • Необходимость в четком прописанном регламенте и стайл-гайде по созданию шаблонов, вью-моделей и расположению файлов в файловой системе
  • Требуется более тесное взаимодействие фронт и бэк-команд для согласования «нарезания» шаблонов и блоков (да, это и плюс и минус)


Я пробовал все описанные подходы. Мой опыт говорит, что в зависимости от типа проекта при прочих равных лучше всего работают первый и последний варианты.

Причем здесь БЭМ?


Пожалуй, БЭМ – одна из наиболее холиворных тем современности, поэтому не могу не вставить картинку ниже.

.

Я пробовал работать с «БЭМом» и «семантичной» версткой и пришел к выводу, что постоянные изменения требований и модификации приводят к частой необходимости в смене разметки и завязываться на имена тегов и каскады в CSS – идея так себе.

Чем плохи каскады?

Идея «выкинуть» из «каскадных» страниц стилей каскад на первый взгляд кажется крамольной, но:
  • Большинство браузеров обрабатывает стили справа-налево и разница в скорости рендеринга .some-block .some-element li>p a и .some-block__link может достигать нескольких раз и с этим нужно считаться.
  • Каскады очень сложно поддерживать и дорабатывать, сложно создавать реиспользуемые компоненты.
  • Отказ от ID в стилях избавляет от конструкций вида
    #some-element p,
    #some-other-element p,
    #one-more-fucking-id p,
    .what-the-hell-class-name p.is-doing-here{
    /*…*/
    }
    

  • «Классический» CSS рекомендует, но не диктует четких правил и регламентов, соответственно Васе может не нравится, как верстает Федя и наоборот. БЭМ предполагает единую методику, поэтому Вася и Федя делают все одинаково – по методологии. Это неплохо повышает bus factor на проекте и уменьшает время поиска необходимого стиля.
  • Концепция блоков, элементов и особенно модификаторов очень хорошо подходит для адаптивного дизайна, когда требуется отображать разные блоки/ или отображаться блоки/элементы по-разному элементы в зависимости от размеров экрана.
  • Блок, элемент и модификатор – удачные термины для коммуникации между разными специалистами. Они достаточно интуитивные, чтобы не «не-технари» не боялись этих слов и одновременно связаны с определенными техническими приемами.

    Эти факты заставляют меня считаться с БЭМ и терпеть уродливые имена классов. Однако, даже сами авторы БЭМа настаивают на том, что БЭМа – методология, может и должна быть «допилена» под нужды проекта и команды. Для этого команде нужны чеклисты.


Мой чеклист


Общие требования

  1. Верстка должна быть кроссбразуерной и по сетке, допускается исправление ошибок в отступах в дизайне
  2. Верстка должна быть реализована по БЭМ-методологии
  3. Верстка должна проходить w3c-валидацию
  4. Верстка удовлетворять требованиям этого чек-листа
  5. Таблицы должны использоваться только для представления табличных данных, вложенные таблицы запрещены

Формы

  1. Формы всегда должны быть оформлены с помощью тега form, тег должен содержать атрибут action
  2. Кнопки должны быть оформлены тегами input или button
  3. Для телефонов необходимо использовать маску ввода
  4. Должна быть реализована валидация

БЭМ

  1. Запрещено использовать id элементов и имена тегов, кроме исключений ниже, для задания стилей
  2. Классы должны именоваться по следующему принципу: some-block__ some-element_ some-modificator
  3. Запрещено использование inline-стилей
  4. Названия блоков и элементов должны соответствовать их назначению и функции, а не тому, как они отображаются.
    Если блоки выполняют разные функции, но выглядят одинаково, их нужно оформить как один блок с нейтральным названием, отражающим их сходство. Нет излишнему дублированию кода
  5. Необходимо использовать нормализацию для всех тегов, которые не могут иметь имени класса (случаи описаны ниже), использование reset.css не допустимо. Использование normalize.css допустимо, ровно как и вариант нормализации только для тегов, для которых невозможно задать класс
  6. Запрещено использовать каскадные стили, глубиной более одного элемента (например table td), за исключением следующей ситуации: в зависимости от примененного модификатора блока, дочерние элементы/блоки должны отображаться по-разному. Каскад будет коротким, при динамическом переключении модификатора java-script реализация гораздо проще и эффективнее с точки зрения взаимодействия с DOM, чем в случае модификации стилей всех дочерних элементов.
  7. Прификсы b- для блоков не используются
  8. Глобальные модификаторы должны быть объявлены отдельным классом, например _uppercase. Underscore в начале указывает, что это модификатор, а не блок. Для адаптивной верстки необходимо использовать глобальные модификаторы _desktop, _tablet и _phone для блоков, которые нужно отображать только на определенном девайсе. Предпочтительно использовать подход mobile-first: от простого – к сложному
  9. Стили должны быть применены к тегам через родительский каскад в случаях, когда невозможно контролировать классы элементов, например:
    • Контент вводит пользователь через форму на сайте, создается динамически или попадает из других источников, неподконтрольных нам
    • Элементы управления в форме: предпочтительно использование родительского каскада, потому что элементы формы могут создаваться с помощью серверного кода. Потребуется дополнительное переформатирование, чтобы сохранить стили элементов. Это нежелательно.

Форматирование и файловая система

  1. Использование одного большого CSS-файла или JS-файла недопустимо, необходимо использовать разветвленную файловую структуру, а именно:
  2. Каждый блок располагается в своей папке, повторно используемые блоки и основной лейауты располагаются в папке shared.
  3. Описание блока и всех элементов располагается в одном файле, именуемом <BLOCK_NAME>.css. Если описание блоков и элементов превышает 600 строк, необходимо декомпозировать его
  4. Имена классов и CSS-правила сортируются по-алфавиту
  5. Модификатор должен переопределять не более 40% стилей, в противном случае лучше создать новый блок
  6. Html-шаблон блока находится в той-же папке (используется серверная или клиентская технология шаблонизации)
  7. Лейауты отделены от страниц, все необходимые страницы «нарезаны» отдельными файлами

Бандлинг, минификация и сборка

  1. Все ресурсы должны быть подготовлены для продакшна и разделены на бандлы. Бандлы следует группировать таким образом, чтобы их количество было минимальным, а вес бандла не превышал 250КБ.
  2. Допускается и поощряется использование серверной технологии для разбиения html-макетов на лейауты, страницы и блоки
  3. Сдача-приемка производится после «сборки». Результатом является n html-страниц и файл index.html со ссылками на все сверстанные страницы. Допустимо передавать верстку в «исходниках», с приложенным bat/make-файлом и «сборщиком», если размер «сборщика» не превышает 10МБ и гарантированно может быть запущен на ОС принимающего верстку.
  4. Ссылки в css и js файлах должны быть абсолютными, в противном случае есть риск, что они не будут корректно работать после минификации



Подборка хороших материалов по БЭМ:



Просто офигенный getting started guide для новых сотрудников

Использовать в качестве чек-листа сложно из-за масштабности этого документа: habrahabr.ru/post/114256. Тут сокращенный вариант, который подойдет в качестве чек-листа: github.com/delka/html5checklist.

Проверка БЭМ

s=document.createElement('script');s.src ="//2gis.github.io/makeup/autoload/script.js";document.body.appendChild(s)
Максим Аршинов @marshinov
карма
85,0
рейтинг 5,6
Управление разработкой бизнес-приложений
Самое читаемое Разработка

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

  • –2
    Автор, хоть бы расшифровал бы разок, что тако БЭМ…
    А то — БЭМ-БЭМ-бах-бах… ;)
    • +1
      Блок, элемент, модификатор: ru.bem.info
      • +2
        Нет, я умею пользоваться поисковиком.
        Я имел в виду, что в подобной статье, следует давать хоть какое-то определение объекту обсуждения, чтобы статья имела целостный вид. Ведь целевая аудитория — не только те, кто уже знает, что такое БЭМ.
        • –2
          Я давно для себя решил, что есть те, кто ищет возможности и, те кто ищет оправдания. Моя таргет груп- только первые.
          • 0
            Независимо от того, что именно Вы для себя решили, это кое-что говорит о Вас как об авторе статей. :)
            • 0
              Что говорит?
              • 0
                Что Вы зазнались и что Вам еще учиться и учиться. :)
                • +2
                  Ну буду учиться тогда, че нет то)
                  • +1
                    Слова не отрока, но — мужа ;)
  • +2
    Фронтэндщику нужно держать два набора инструментов и переключаться между ними
    Фронтэндщику сложно использовать незнакомую технологию, всякие…
    Фронтэндщик может «сломать» серверный код и не понять этого
    Фронтэндщик не знает стандартов кодирования бэкэнд-команды
    Фронтэндщику нужно разворачивать и конфигурировать все приложение в т.ч. БД и другие зависимости

    Автор описал какого-то очень плохого фронтендщика. У нас никогда не было с этим проблем.
    • +1
      Почему? Ситуации вполне себе реалистичные.
      • +2
        Может быть это вопрос скиллов самого фронтендщика и тех договоренностей, которые есть внутри команды. Если фронтендщик работает с RoR или ASP.NET MVC, то он обязан знать какую-то минимальную информацию о них. Тот же Razor в шаблонах для ASP.NET MVC знать нужно обязательно, а он потянет за собой желание написать какой-нибудь html-хелпер, который сократит разметку. Так или иначе, но фронтэнд корнями стоит на бекенде (За исключением REST API и SPA). А принятые в компании гайдлайны по разработке не так сложно прочитать и применять, в этом я тоже не вижу сложности (разве что природная лень).
        • –1
          Конкретно моя боль в следующем:
          • Visual Studio — не лучший инструмент для верстки
          • Необходимость разворачивать БД и весь сложный стек на машине разработчика, которое это, все строго говоря, не нужно
          • Необходимость многократно перекомпилировать приложение (на это уходит время)

          Для скриптовых языков проблема стоит не так остро. Хочу проверить одну гипотезу: я на досуге отвязал Razor от ASP.NET MVC. Хочу попробовать сделать таск для gulp для полноценной сборки .cshtml на gulp watch, чтобы можно было сразу верстать в терминах блоков.
          Вью модели компилировать на лету в фоновом режиме из указанных в конфиге сборок/папок, чтобы не нужно было постоянно жать на cntrl+shift+b: отредактировал модельку, пошел править шаблон, пока правил вью модельки скомпилировались.

          Получится, что обе команды работают над одной кодовой базой, но точки входа у них разные: для backed — полноценное приложение, а для frontend — легковесный сборщик со stub'ами для инстанцирования вью-моделей. Смысл этого в сокращении накладных расходов.

          Я не спорю с тем, что научиться редактировать серверный код — не рокет сайнс, я пытаюсь сократить накладные расходы на переключение контекстов.
          • +1
            У меня рядом с Visual Studio открыт WebStorm. Студия чаще всего просто свернута. А если есть возможность на локальном IIS развернуть проект, то студия вовсе не открывается.
  • +1
    Посмотрите еще на getbem.com, там есть ссылки на статьи по методологии и небольшое FAQ.
  • 0
    Спасибо! Статья была очень интересна для меня и разложила мысли по полочкам.
  • +2
    Вот ещё накину
    source.futurecolors.ru/css-requirements/

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.