День 94
Jon Snow
1 ноября 2017, 06:26

Дело помаленьку двигается. Хочется, конечно, нарастить темп, но отдых тоже нужен :)

Сегодня сделал разметку по BEM и подумал над поведением блоков при масштабировании (про масштабирование я напишу вместе с началом стилизации в следующем посте, а то уже длиннопост вышел).

Я знаю, среди моих читателей есть люди, которые так же, как и я, изучают верстку и в частности BEM. Так вот, специально для вас я сделал и разобрал разметку <header'а с комментариями, как я обозначал блоки и элементы. Для наглядности, так сказать.

На всякий случай ссылочки по BEM (информация вполне может оказаться для кого-то из вас новой!).

А, да. Не претендую, что прав абсолютно во всех утверждениях и что мое решение идеально - вполне может быть, более опытные разработчики найдут ошибки или видят иной путь реализации, лучший, чем мой. Однако, все дальнейшие рассуждения по максимуму (по крайней мере, я старался :) ) аргументированы, и их логика может помочь вам правильно размечать блоки по BEM. Лучше всего одновременно читать и смотреть на разметку с макетом, чтобы было всё наглядно.

  1. С header всё понятно - естественно, это блок. Название класса header само собой напрашивается (как самое простое, да и как вообще можно назвать класс хедера?)
  2. В хедере две секции. Они могут перемещаться внутри хедера относительно друг друга, вполне самостоятельны с точки зрения контента и не влияют друг на друга с точки зрения позиционирования (мы можем разместить контакты под мэйном и смысл хедера от этого не изменится!) - поэтому их нужно именовать как два вложенных (относительно хедера) блока. Их собственные названия, вообще говоря, contacts & main-menu & socials & search-form. ВОПРОС: могут ли данные блоки встречаться сами по себе за пределами хедера где-то ещё? Ответ на него - да (кстати, в футере есть список контактов и соцсетей тоже!), и ещё - я даже могу вынести данные блоки за пределы хедера, если, например, хочу, чтобы они менялись на других страницах. Посему, их лучше назвать не как класс с привязкой к хедеру (header-contacts, например), а как блок с модификатором, указывающим, что они принадлежат хедеру: contacts_header & main-menu_header. Заметьте, здесь и далее я использую соглашение по именованию CamelCase.
  3. Рассмотрим секцию contacts_header. В ней четыре вложенных компонента: заголовок (имеющий чисто функциональную роль, в соответствиями с правилами семантичной разметки), список, в котором размещены реквизиты компании-оунера, список групп компании в соцсетях и форма поиска. Так вот. Заголовок, с одной стороны, должен иметь функциональный класс, который будет его скрывать. В моей верстке для этого я использую класс visually-hidden (просто как удобный класс с запоминающимся названием). С другой стороны, данный заголовок является неотъемлемой частью секции (так как согласно текущему HTML 5.1 и готовящемуся к продакшену HTML 5.2 семантические блочные элементы сеток, такие как article и section, не валидны без заголовков), заголовок зависим от своей секции по контенту (и позиционированию - в самом хедере это не видно, но вообще по макету это так), и несмотря на то, что внутри секции h2 можно перемещать (флексом), это элемент. Поэтому, согласно BEM, нужно ему дать второй класс contacts__title_header (всё верно, сперва имя блока - потом __имя элемента - потом _имя модификатора (мой модификатор указывает на секцию, а не на своё имя, посему тут значение не нужно). Обратите внимание: я собираюсь скрывать данный заголовок с помощью visually-hidden, поэтому, по идее, мне не нужны для него какие-то другие стили кроме стилей visually-hidden (которые его скрывают). Однако, если предположить, что (при внесении неких правок) я данный заголовок всё же отображаю - у меня уже будет класс (block__title_modifier), с помощью стилей которого возможно быстро внести данные правки. Таким образом, у меня получился микс: с одной стороны, заголовок есть элемент своей секции, с другой стороны - это функциональный блок, который мы скрываем. По макету: видимые заголовки также отличаются видом в зависимости от секции - в них также, нужно будет указывать структуру block__title_modifier для стилизации. Причем block__title можно использовать только для задания формата текста и его дефолтного цвета, а с помощью _modifier мы легко переопределим какой-то из этих параметров (точно понадобится менять цвет). Если сделать разметку и стили таким способом, то фактически стили всех заголовков уже будут - нужно будет просто вешать или удалять класс visually-hidden для их скрытия или показа (тогда как при обычном подходе пришлось бы делать новые стили при каждой такой правке).
  4. Что касается списка контактов оунера. Список - это блок, поскольку функционально независим, его можно тягать туда-сюда по секции, он встречается в макете ещё раз (в футере). У него есть собственное имя info, но его вид определяется тем, в какой секции он размещен (например, он флекс-контейнер в хидере - а в футере это список). В футере он выглядит по-другому, чем в хедере. Поэтому, необходимо дать ему модификатор, который будет указывать, в какой секции он размещен (например, info_header указывает, что это стиль для блока info в хедере, info_footer - для футера).
  5. Разберемся с элементами списка и ссылками в info. Элементы списка не могут быть отдельными элементами от самого списка - это элементы с именованием info__item. Однако, они могут по-разному себя вести (с точки зрения позиционирования) в разных реализациях info для хедера и футера. Посему, необходимо дать им тот же модификатор _header (и _footer), что есть у нас для заголовков.
  6. Внутри li находятся ссылки с текстом реквизитов. Это не те ссылки, по которым мы переходим на другие страницы. Задумка такова: я нажимаю на телефон - открывается некое средство (viber, допустим), с которого можно позвонить оунеру (или просто появляется запрос "хотите позвонить?"), жмём на мэйл - открывается почтовый ящик, с которого можно послать на тот адрес мэйл, и т.д. Реализация данных механизмов - прерогатива не верстальщика. Однако, ссылки в себе будут содержать стили, определяющие их вид на странице. Опять же, понятно, нам понадобится определять, где находится ссылка, поэтому опять понадобятся модификаторы _header и _footer. Поскольку список ссылок - семантичная обертка для блока info со ссылками внутри (если бы я "на дивАх" верстал, так бы и было!), ссылки эти нельзя использовать вне info - а значит, они - элементы info__link, вложенные в info__item (так делать можно и нужно, когда нет необходимости в создании служебных блоков).
  7. Абсолютно аналогична ситуация и со списком соцсетей socials. Этот список - тоже по тем же причинам блок, его li - элементы с __item, его ссылки - тоже его элементы __link, вложенные в __item. И тоже там понадобятся модификаторы _header (сюда) и _footer (в футер), чтобы внести разницу в стилях для блока (заметьте, что для реализации данного блока в футере - секция Follow Us - различается в макете для хедера и футера гораздо сильнее, чем список контактов).
  8. Форма поиска. Да, это именно форма, а не просто поле ввода. Сама форма с точки зрения BEM - блок с именем search-form. В отличие от списков, он уникален для страницы, поэтому его можно рассматривать как вложенный блок для хедера. Поэтому, его можно именовать как header-search-form (header указывает на то, что форма в хедере и только в нём, search придаёт форме смысл - так коллега из, допустим, Уганды легко догадается по коду, что это стиль именно для формы поиска!).
  9. Label необходим в данной форме для того, чтобы сохранить структуру формы с точки зрения её доступности (для машин и для "читалок"), поэтому мы должны его скрыть (visually-hidden мне в помощь :) ). Также, label связан с полем поиска - следовательно, влияет на иные компоненты внутри блока и не используется отдельно от них - посему, это точно элемент с именем header-search-form__search-label. Здесь не нужны модификаторы. В итоге - получился микс, поскольку мы использовали лейбл и как функциональный блок (отображающий текст для машин и читалок), и как элемент формы поиска.
  10. Инпут в ней актуален только для данной формы, и без него форма не имеет никакого смысла (поскольку некуда будет вводить запрос на поиск). Значит, этот input - элемент c именем header-search-form__search-input. Все стили для него вполне возможно написать прямо в нём, и не будут меняться в зависимости от того, в какой части макета он находится. Значит, модификаторы здесь не нужны.
  11. Секция main-menu. Тут в целом всё просто и аналогично. h2 у нас тут выполняет ту же функцию, что и в пункте 3 - у него та же реализация. nav, точно так же, как было описано в пп. 4-7, является блоком, содержащим список ссылок (его вложенный блок!), у которого есть элементы списка и элементы-ссылки. А вот с logo (который, бесспорно, является блоком!) ситуация интереснее.
  12. Давайте посмотрим, какова структура блока logo. В нём есть три составных компонента: картинка, главная надпись (TripFInder) и вспомогательная надпись. Причём картинка, учитывая то, что в макете это иконочный символ FontAwesome, (для джумлы! :) ), реализуется в качестве псевдоэлемента (вопрос для какого элемента - но это уже проблема стилизации). Учитывая то, что логотип является единым целым, все вложенные в logo компоненты влияют друг на друга и не используются нигде отдельно. Значит, это всё элементы. Учитывая то, что логотип единообразен (и, кстати, для данного макета вообще уникален на странице), нужно понимать, что модификаторы здесь не нужны - всю стилизацию можно выполнить с помощью стилей самих элементов. Кстати, есть вариант обернуть логотип в ссылку - но учитывая специфику макета, тут не на что переключаться, и логотип, который вообще по нажатию ведет на главную страницу, можно оставить так.

По абсолютно тем же принципам сделана и вся остальная разметка. Мне нравится то, что получилось. В целом, могу сказать, что методология неплоха как минимум потому, что делает именования единообразными, а код - более читабельным. Хотя, недостаток - необходимо время на то, чтобы создать в своей разметке классы по BEM (уменьшается с опытом и у разработчиков есть инструмент автоматизации - я только в первый раз для понимания всё ручками делал). Плюс, классы получились "развесистыми" по количеству символов - конечно, это компенсируется отсутствием сложных селекторов в стилях, но тем не менее. Может, это именно у меня так получилось, или всё зависит от структуры макета :) В общем, первый опыт использования BEM явно был полезен и интересен.

P.S. В BEM существует своя файловая структура и сборщики, которые пока для меня тёмный лес. Сейчас я не стану их трогать и ограничусь только разметкой и стилями по BEM. Я начинал делать раньше ещё один макет - называется Agnecy (не опечатка, видимо его так назвали чтобы отличать от других) - возможно, там как раз и применю BEM полностью, как его рекомендуется применять.

P.P.S https://echo.htmlacademy.ru - указывая его в форме в атрибуте method, можно тестить, какие данные и в каком виде отправляются с вашей формы на сервер. То есть, это самый простейший и бесплатный эмулятор сервера, который покажет, если вы хотите затестить форму, те данные, которые пересылаются с неё, без необходимости работы с самим сервером и его настройки. С его помощью хорошо ловить баги обработки данных в форме, особенно если вы где-то что-то меняли в логике обработки, вычисляете отправляемые значения или пользуетесь скрытыми полями. Вполне удобно :)

Нравится? Расскажите друзьям!
Комментировать
Перейти к записи в ленте
Цель

Вы тоже можете
опубликовать свою
цель здесь

Мы поможем вам ее достичь!

310 000

единомышленников

инструменты

для увлекательного достижения

Присоединиться
Регистрация

Регистрация

Уже зарегистрированы?
Быстрая регистрация через соцсети
Вход на сайт

Входите.
Открыто.

Еще не зарегистрированы?
 
Войти через соцсети
Забыли пароль?