Верстка современных web-проектов – это сложно, долго и дорого. Казалось бы, с переходом IE на автоматические обновления, HTML5, окончанием поддержки Win XP все мы должны зажить в сказочной стране с пони и радугой. Почему легче не стало?
Хочется:
Пожалуй, БЭМ – одна из наиболее холиворных тем современности, поэтому не могу не вставить картинку ниже.
.
Я пробовал работать с «БЭМом» и «семантичной» версткой и пришел к выводу, что постоянные изменения требований и модификации приводят к частой необходимости в смене разметки и завязываться на имена тегов и каскады в CSS – идея так себе.
- 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 на проекте и уменьшает время поиска необходимого стиля.
- Концепция блоков, элементов и особенно модификаторов очень хорошо подходит для адаптивного дизайна, когда требуется отображать разные блоки/ или отображаться блоки/элементы по-разному элементы в зависимости от размеров экрана.
- Блок, элемент и модификатор – удачные термины для коммуникации между разными специалистами. Они достаточно интуитивные, чтобы не «не-технари» не боялись этих слов и одновременно связаны с определенными техническими приемами.
Эти факты заставляют меня считаться с БЭМ и терпеть уродливые имена классов. Однако, даже сами авторы БЭМа настаивают на том, что БЭМа – методология, может и должна быть «допилена» под нужды проекта и команды. Для этого команде нужны чеклисты.
Мой чеклист
Общие требования
- Верстка должна быть кроссбразуерной и по сетке, допускается исправление ошибок в отступах в дизайне
- Верстка должна быть реализована по БЭМ-методологии
- Верстка должна проходить w3c-валидацию
- Верстка удовлетворять требованиям этого чек-листа
- Таблицы должны использоваться только для представления табличных данных, вложенные таблицы запрещены
Формы
- Формы всегда должны быть оформлены с помощью тега form, тег должен содержать атрибут action
- Кнопки должны быть оформлены тегами input или button
- Для телефонов необходимо использовать маску ввода
- Должна быть реализована валидация
БЭМ
- Запрещено использовать id элементов и имена тегов, кроме исключений ниже, для задания стилей
- Классы должны именоваться по следующему принципу: some-block__ some-element_ some-modificator
- Запрещено использование inline-стилей
- Названия блоков и элементов должны соответствовать их назначению и функции, а не тому, как они отображаются.
Если блоки выполняют разные функции, но выглядят одинаково, их нужно оформить как один блок с нейтральным названием, отражающим их сходство. Нет излишнему дублированию кода - Необходимо использовать нормализацию для всех тегов, которые не могут иметь имени класса (случаи описаны ниже), использование reset.css не допустимо. Использование normalize.css допустимо, ровно как и вариант нормализации только для тегов, для которых невозможно задать класс
- Запрещено использовать каскадные стили, глубиной более одного элемента (например table td), за исключением следующей ситуации: в зависимости от примененного модификатора блока, дочерние элементы/блоки должны отображаться по-разному. Каскад будет коротким, при динамическом переключении модификатора java-script реализация гораздо проще и эффективнее с точки зрения взаимодействия с DOM, чем в случае модификации стилей всех дочерних элементов.
- Прификсы b- для блоков не используются
- Глобальные модификаторы должны быть объявлены отдельным классом, например _uppercase. Underscore в начале указывает, что это модификатор, а не блок. Для адаптивной верстки необходимо использовать глобальные модификаторы _desktop, _tablet и _phone для блоков, которые нужно отображать только на определенном девайсе. Предпочтительно использовать подход mobile-first: от простого – к сложному
- Стили должны быть применены к тегам через родительский каскад в случаях, когда невозможно контролировать классы элементов, например:
- Контент вводит пользователь через форму на сайте, создается динамически или попадает из других источников, неподконтрольных нам
- Элементы управления в форме: предпочтительно использование родительского каскада, потому что элементы формы могут создаваться с помощью серверного кода. Потребуется дополнительное переформатирование, чтобы сохранить стили элементов. Это нежелательно.
Форматирование и файловая система
- Использование одного большого CSS-файла или JS-файла недопустимо, необходимо использовать разветвленную файловую структуру, а именно:
- Каждый блок располагается в своей папке, повторно используемые блоки и основной лейауты располагаются в папке shared.
- Описание блока и всех элементов располагается в одном файле, именуемом <BLOCK_NAME>.css. Если описание блоков и элементов превышает 600 строк, необходимо декомпозировать его
- Имена классов и CSS-правила сортируются по-алфавиту
- Модификатор должен переопределять не более 40% стилей, в противном случае лучше создать новый блок
- Html-шаблон блока находится в той-же папке (используется серверная или клиентская технология шаблонизации)
- Лейауты отделены от страниц, все необходимые страницы «нарезаны» отдельными файлами
Бандлинг, минификация и сборка
- Все ресурсы должны быть подготовлены для продакшна и разделены на бандлы. Бандлы следует группировать таким образом, чтобы их количество было минимальным, а вес бандла не превышал 250КБ.
- Допускается и поощряется использование серверной технологии для разбиения html-макетов на лейауты, страницы и блоки
- Сдача-приемка производится после «сборки». Результатом является n html-страниц и файл index.html со ссылками на все сверстанные страницы. Допустимо передавать верстку в «исходниках», с приложенным bat/make-файлом и «сборщиком», если размер «сборщика» не превышает 10МБ и гарантированно может быть запущен на ОС принимающего верстку.
- Ссылки в css и js файлах должны быть абсолютными, в противном случае есть риск, что они не будут корректно работать после минификации
Подборка хороших материалов по БЭМ:
- habrahabr.ru/company/yandex/blog/234905
- habrahabr.ru/post/171437
- ru.bem.info/method/history
- habrahabr.ru/post/203440
Просто офигенный 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)