Семантический CSS
Перевод статьи Semantic CSS с сайта snook.ca, опубликовано на css-live.ru с разрешения автора — Джонатана Снука.
Подзаголовок: почему все, кто говорит о важности семантики — правы и неправы одновременно.
Я часто слышу про семантический CSS. Что ID и классам нужно давать осмысленные имена.
Видимо, люди неявно полагают, что слово «семантический» говорит само за себя. Но на практике это не всегда так. Конечно, можно сделать умный вид и согласиться с тем, что, например, класс «.products» семантический.
Так что же люди подразумевают под семантическими названиями классов. Как правило, эти названия должны описывать содержимое элементов.
Например, название класса «products
» подошло бы списку продуктов. А «events
» — списку событий. И так далее.
Система наименования не смотрит на внешний вид элементов. Она описывает то, что они из себя представляют.
Почему нам нужен класс, описывающий контент?
В случае микроформатов осмысленные названия классов помогают другим сайтам, приложениям и дополнениям правильно встраивать данные. Есть с дюжину разных спецификаций, которые можно использовать в проекте.
Однако при оформлении браузеры не волнует смысл в названии классов. Это важно только для нас — людей, и толку от этой семантики мало. Какая вам разница, относится ли этот список к продуктам или нет? Даже если вы знаете, что это список продуктов, как это поможет при оформлении?
Я заметил, что люди, использующие этот тип семантических классов, не всегда последовательны в том, как они используют их на протяжении всего проекта.
Наряду с products
, events
и collections
они используют назввания классов navigation
, dropdown
и modal
, которые на самом деле не описывают контент. Они описывают роль стилей в дизайне.
Роль стилей в дизайне
Описание роли стилей в дизайне — за что на самом деле отвечает элемент — это важно. В дизайне мы используем паттерны, чтобы дать пользователям доступный для изучения и единообразный интерфейс. Эти паттерны закрепляются и в CSS. Таким образом, названия классов дают нам полезные подсказки при построении интерфейса.
Названия, описывающие роль стилей в дизайне, гарантируют, что мы используем (и повторно используем) элементы интерфейса правильным образом.
Если определять products
, events
и collections
по отдельности, то между этими интерфейсами рано или поздно возникнет разбежка. (Хотя, да, люди борются с этим с помощью функции расширения в препроцессорах (extend)). Использование лишних классов, где достаточно и одного, также приводит к раздутию CSS-файлов.
Говорят, в программировании есть две сложности: ошибки неучтенной единицы и именование сущностей.
Например, на странице мастер-класса SMACSS.com было несколько адресов, которые я выделил синим фоном и загруглёнными углами. Я назвал их location
, поскольку так выделялся каждый адрес, где я проводил мастер-класс.
При открытии интернет-магазина, у меня был список продуктов, в котором мне хотелось выделить каждый продукт с помощью такого же паттерна дизайна. Проблема в том, что они не были адресами. Они были продуктами. Однако, будучи ленивым разработчиком, я просто снова воспользовался классом location
, применив его к моим продуктам. Явно не идеал (но что поделать, зато это работало)!
Задачей этих стилей было выделить что-то. Вот как мне следовало это назвать!
В начале проекта может показаться, что стили понадобятся только в одном месте. По ходу развития проекта эти «одноразовые» стили часто переползают и в другие элементы на сайте. Если выбрать название класса, которое описывает роль в оформлении, а не содержимое, нам будет гораздо приятнее заново использовать этот CSS.
После стольких лет разработки я по-прежнему инстинктивно использую названия классов, основанных на содержимом, а не на функции. Мне приходится быть старательным и внимательным в этом деле.
Общие функции
Иногда придумать название класса, описывающее роль элемента в дизайне, легко — скажем, button (кнопка), navigation (навигация) или dropdown (выпадающее меню). А иногда, если у элемента нет такой явной функции, это может быть крайне трудно.
Взгляните на этот пример из сайта Twitter:
Карточки Twitter с призывом к действию
Как бы вы это назвали? Это cards
? Тут возникает путаница, поскольку Twitter называет словом cards
(«карточки») свои встроенные твиты. Вот в чем загвоздка.
Я помню в «Yahoo!» у нас была похожая дилемма при разработке новой функции. Как назвать общий контейнер с изменяющийся контентом? Перерыв словарь, мы в итоге остановились на слове pod
. Но мне до сих пор неловко от этого названия.
Вот где пригодилась бы документация. Если в вашем проекте есть card
, box
и pod
, то как решить, что из них выбрать?
Спорные случаи
Некоторые названия могут плясать от содержимого, но также и от функции.
Давайте взглянем на сайт Engadget:
Карточки Engadget с призывом к действию
Engadget называет каждый из них lede
(вводный абзац). Это кажется описанием содержимого, но как по мне, так здесь все признаки функционального имени. Цель этой части дизайна — представить вводный абзац. article
(статья) и lede
(вводный абзац) достаточно общие и подходят почти для любого контента, будь то техническая, передовая или новостная статья, или любая другая.
Что, если Engadget захочет представить вводные абзацы в разных визуальных стилях? Это уже сложнее. Почему? Потому что мне нравится, чтобы у компонентов был индивидуальный визуальный стиль. Если у каждого вводного абзаца индивидуальный визуальный стиль, я бы не стал использовать для них одно корневое название модуля.
Например, в SMACSS модуль назывался бы lede
. Если мы назвали отличающийся, но особый стиль lede
, как lede--special
, тогда нужно понимать, что этот особый стиль задуман быть отдельным, а не надстройкой над стандартным lede
. И это также означает, что другие разновидности и дочерние элементы, вероятно, не состыкуются с этим вариантом.
В этом случае придумайте уникальное название модуля. Например, special-lede
, uber-lede
, intro
или любое, которое придумает ваша команда.
Хоть розой назови ее…
Пожалуй, каждый мой нынешний пост надо бы сопровождать оговоркой. Это не догма. Это процесс, с которым я подружился. Более вдумчивый подход к именованию, с оглядкой на будущее, избавил от необходимости рефакторить код так часто.
Мой класс location
(«адрес») для выделения product-ов никого не обидел. Никто не умер. Здание не обрушилось. Конец света не наступил. Но порой даже чуть-чуть более ясный код может превратить поддержку проекта из мучения в радость.
P.S. Это тоже может быть интересно:
Отличная статья. Тоже сталкиваюсь с этим, например называешь список анонсов .anons-list, затем в таком же оформлении хочется еще что-нибудь сделать и ты копируешь стили и придумываешь новый класс .something-list. А проще было бы использовать типа block-list, а другие вещи выводить с надстройкой. Например, если в списке будет 4 или 5 элементов в строку, можно сделать block-list—four или block-list—five =)
Приятно, что я не одинок. Я так же пытался, чтобы название классов обозначало содержимое блока. Но потом быстро понял, что если хочешь работать эффективно надо писать так, чтобы не переписывать на каждом проекте всё заново, а чтобы как можно большие куски кода просто копировать из проекта в проект. В одном случае это может плитки с товаром, а в другом блог статей или что-то ещё.