Научитесь работать в группе CSS. Рекомендации по CSS для групповой разработки

Эмили Льюис (Emily P. Lewis) | 5 мая 2010 г.

Сколько раз вы принимали проект, который начинал кто-то другой, и обнаруживали, что первоначальный код автора проекта находится в ужасном беспорядке? Возможно, вам приходилось работать с несколькими членами группы, каждый из которых писал код в своей собственной манере? Или возможно, вам доводилось заглянуть в проект, созданный вами несколько лет назад, и обнаружить, что вы не помните ход ваших мыслей?

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

Если бы этот поставщик просто следовал некоторым базовым рекомендациям в своих CSS, было бы сохранено драгоценное время и деньги моего работодателя, не говоря уже о том, что мое душевное равновесие было бы в гораздо лучшем состоянии. В этой статье будут даны рекомендации по созданию CSS, чтобы помочь избежать несогласованности и избыточности; фактически будут установлены стандарты, рационализирующие групповую разработку.

Будьте организованными!

Хорошая организация — основа хорошо написанных CSS. Она помогает мне, а также любому, кто будет обновлять код в будущем, понимать и проверять CSS, а также более быстро переходить к конкретным стилям.

Прежде чем приступить к созданию стилей, я определяю структуру моего документа CSS в соответствии с различными «разделами» контента веб-страницы, дизайн которой я разрабатываю. Обычно эти разделы одинаковы в большинстве веб-сайтов:

  • верхний колонтитул;
  • раздел навигации;
  • раздел основного контента;
  • боковая панель;
  • нижний колонтитул.

Поэтому в моем файле CSS я добавляю комментарии, указывающие, где будут использоваться стили для каждого из этих разделов:

/*---GLOBAL---*/ (глобальный)
/*---HEADER---*/ (верхний колонтитул)
/*---NAV---*/ (раздел навигации)
/*---CONTENT---*/ (контент)
/*---SIDEBAR---*/ (боковая панель)
/*---FOOTER---*/ (нижний колонтитул)

Обратите внимание, что самый первый добавляемый мной структурный комментарий — GLOBAL. Этот раздел не соответствует конкретному контенту моего сайта, но указывает место, в котором я задаю то, что называю «глобальными» стилями. Это универсальные стили, не предназначенные для какого-либо определенного контента, например стили для макета и структуры, типографических элементов (таких как заголовки, параграфы, списки и ссылки), форм (<form>) и таблиц (<table>).

Сохранение этих глобальных, универсальных стилей вверху моего файла CSS помогает мне использовать преимущества каскада. Все CSS, следующие за этими объявлениями стилей, будут соответственно наследовать атрибуты, и впоследствии будет гораздо легче переопределять эти атрибуты при необходимости.

Больше CSS, больше организации

Я работаю с очень большими веб-сайтами, которые ссылаются на огромное количество CSS. Когда приходится иметь дело с таким большим количеством строк стилей, я предпочитаю добавлять дополнительный уровень комментариев в каждом разделе. Например, в разделе GLOBAL я указываю типы стилей, которые задаю:

/*---GLOBAL---*/
    /*--Structure--*/
    /*--Typographic--*/
    /*--Forms--*/
    /*--Tables--*/
/*---HEADER---*/
/*---NAV---*/
    /*--Primary--*/       
    /*--Secondary--*/  
    /*---CONTENT---*/  
/*---SIDEBAR---*/  
/*---FOOTER---*/

Можно также видеть, что я добавила дополнительный уровень комментариев в раздел NAV, указывающий, где будут находиться стили для основной и дополнительной навигации.

Для ваших целей это может быть излишним. В действительности для небольших сайтов с меньшим количеством CSS я обычно не использую дополнительный уровень комментариев. Но в больших файлах CSS это дополнение оказалось очень полезным для моей группы.

Свобода формата

Формат этих структурных комментариев в конечном итоге выбирается на усмотрение разработчика. В вышеприведенном примере просто показан выбранный мной и моей группой способ. Некоторые предпочитают задавать структурные комментарии в две строки:

/*   HEADER      
------------------------------*/

Некоторые используют специальный символ, например знак равенства (=), в качестве флага для помощи при поиске в текстовом редакторе:

/*   =Header      
------------------------------*/

Некоторые не используют дополнительный уровень комментариев. Кроме того, существуют сообщества, использующие совершенно другую организационную структуру, в которой CSS разделяются не в соответствии с контентом страницы, а по типам элементов, таким как заголовки, изображения, списки и т.п. Главное — определить предпочтительный формат и придерживаться его.

Хотите структурировать в соответствии с элементами контента? Никаких проблем. Хотите указывать комментарии строчными буквами — делайте это. Не хотите вводить второй уровень комментариев? Не вводите. Не нравятся дефисы и хотите использовать точки? Пожалуйста. Только делайте то, что имеет больше смысла для вас и вашей группы.

Комментарии для общения

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

Что, кто, когда

При работе в группе особенно полезно сообщать другим членам группы, для сего предназначен данный файл CSS, кто его создал, и когда он последний раз изменялся. В моей группе мы добавляем «сводный» комментарий вверху файлов CSS, в котором содержатся следующие сведения:

/*----TITLE: Main screen styles | AUTHOR: EPL | UPDATED: 03/23/10 by EPL----*/

Сведения заголовка полезны при работе с несколькими таблицами стилей, например когда одна таблица стилей используется для экрана, другая для печати, третья для мобильных устройств, и даже для разных трюков в IE. Сведения об авторе позволяют всем членам группы знать, к кому следует обратиться в случае возникновения вопросов по первоначальным CSS, а сведения об обновлении сообщают, когда и кем было выполнено последнее обновление.

Что касается вашего сводного комментария, включайте в него только то, что будет полезно вашей группе. Если сведения об авторе не нужны, пропустите их. Если требуется указание авторских прав, добавьте его. Я даже видела сводные комментарии, в которых указывался адрес и контактные данные:

/*---- IE6 screen styles (ie6.css)  Company ABC 1234 Avenue of the Americas New York, 
NY 10020 http://companyabc.com  Updated: 03/23/10 by EPL ----*/

Цвета

Один из наиболее полезных комментариев CSS, которые я встречала, содержал перечень цветов, в котором определялась цветовая палитра веб-сайта:

/*---COLORS: Green #b3d88c | Blue #0075b2 | Light Gray #eee | Dark Gray #9b9e9e | 
Orange #f26522 | Teal #00a99d | Yellow #fbc112---*/

Перечень цветов особенно полезен на стадии разработки и позволяет не тратить время на подбор цветов или поиск их в каких-либо стилевых руководствах. Требуется узнать шестнадцатеричное значение для синих ссылок? Перейдите к комментарию, скопируйте и вставьте.

В моей группе мы указываем цвета в верхней области наших документов CSS, сразу после сводного комментария и перед всеми объявлениями стилей с сопутствующими структурными комментариями. Мы также стараемся сохранять перечень простым, чтобы обслуживание оставалось простым, но вы можете выбирать сложность цветового набора на свое усмотрение.

Формат — также на ваше усмотрение. Можно указать все определения цветов в одной строке, как показано выше, или разделить их на несколько строк:

/*---ЦВЕТА      
зеленый #b3d88c      
синий #0075b2      
светло-серый #eee      
темно-серый #9b9e9e      
оранжевый #f26522      
сине-зеленый #00a99d      
желтый #fbc112 
---*/

Еще раз, задача в том, чтобы найти формат, лучше всего подходящий для ваших потребностей, и последовательно его придерживаться.

Разработка и отладка

Случалось, что в середине процесса разработки мне необходимо было передать мои CSS другому члену группы. Также бывают ситуации, когда я бьюсь головой об стену, пытаясь понять, почему IE не работает с моими CSS, и мне необходимо уйти. В таких ситуациях комментарии просто необходимы.

Оставьте примечание для себя или коллег из группы, укажите, что это за стиль, и, возможно, что он не полностью завершен:

/*--//--Styling for link states is pending new changes from designer, please don't edit | 
EPL 03/23/10--\\--*/ 
a, a:link, a:visited {    
    color:#0075b2;     
    text-decoration:none;
}  
a:hover, a:focus, a:active {    
    color:#b3d88c;
}

Обычно я оформляю такие типы комментариев не так, как остальные комментарии, чтобы они сильнее выделялись. А также делаю их настолько длинными и подробными, насколько это необходимо. Тут также следует использовать то, что подходит для вас.

Однако при этом не забывайте, что после окончания разработки и отладки рекомендуется избавиться от таких комментариев. Если они больше не нужны для работы, то они также не нужны в CSS. Они только перегружают файлы.

Сбросы

Сбросы CSS становятся весьма популярны. Это стили, добавленные вверху файлов CSS, которые устанавливают базовые значения для элементов HTML, чтобы исключить несоответствия описаний — полей, отбивки, высоты строк и т.п. — в разных браузерах:

/*---RESET---*/ 
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, 
blockquote, pre, a, abbr, acronym, address, big, cite, code, del, 
dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, 
sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, 
caption, tbody, tfoot, thead, tr, th, td {    
    margin: 0;    
    padding: 0;    
    border: 0;    
    outline: 0;    
    font-weight: inherit;    
    font-style: inherit;    
    font-size: 100%;    
    font-family: inherit;    
    vertical-align: baseline; 
}

Этот пример представляет выдержку из скрипта для перезагрузки сброса Эрика Мейера (Eric Meyer), который я часто использую. Но я обычно изменяю его сброс так, чтобы в нем не было не используемых мной элементов разметки, и рекомендую всем делать то же самое. Например, в сайтах, разрабатываемых моей группой, почти никогда не используются элементы <kbd>, <iframe>, <applet> и некоторые другие элементы из показанных выше.

Поэтому я удаляю селекторы этих элементов. Это незначительно уменьшает время загрузки страницы, но я полагаю, что отсутствие ссылок на неиспользуемую разметку помогает исключить путаницу среди членов группы.

Я также изменяю стили сбросов, если не хочу переопределять встроенные стили браузеров, например обработку неупорядоченных списков. В таких случаях я слежу за тем, чтобы эти элементы не включались в объявление стилей.

Однако необходимо уточнить, что сбросы CSS — не для всех. Существует много причин не использовать их. Я считаю, что решение нужно принимать самостоятельно, и если планируется двигаться по пути сброса, необходимо сделать стили сброса максимально четкими и подходящими для конкретного сайта.

Семантическая согласованность имен

Одна из самых раздражающих проблем при работе с чужими CSS — отсутствие всякого смысла в именах классов или идентификаторов. Представьте, что обнаружено следующее:

.f23 {    
    background: #fff;    
    border: 1px solid #ff0;    
    font-weight: bold;    
    padding: 10px; 
}

Я совершенно не представляю, что означает .f23. А еще хуже, когда отсутствуют структурные комментарии, и я не знаю, к какому контенту относится .f23. Это заголовок? Основной контент? Навигация?

В таких ситуациях, особенно в случае большого сайта, скорее всего будет потрачено возмутительно много времени на попытки найти, в каком месте разметки имеется ссылка на это значение класса. Если бы разработчик использовал семантические принципы именования, имеющие смысл и основанные на типе контента, для которого предназначен стиль, то у меня был бы контекст для CSS:

.alert {    
    background: #fff;    
    border: 1px solid #ff0;    
    font-weight: bold;    
    padding: 10px;
}

В данном случае очевидно, что .alertпредоставляет значительно больше информации о контексте для CSS по сравнению с произвольной комбинацией букв и цифр.

Однако семантический контекст наименования кроме предоставления контекста также помогает сохранить время. Представим компанию, которая часто изменяет фирменную символику. Если разработка CSS выполнялась с использованием описательных, а не семантических значений классов и идентификаторов, то придется просматривать гораздо больше CSS, а возможно и разметки, чем это необходимо.

Например, предположим, что выполнено назначение class="blueBox" выносному полю на сайте с использованием синей цветовой палитры компании. Затем в компании создается новая символика (ребрендинг), и цветовая палитра компании меняется на красную. В результате blueBox теряет смысл. Таким образом, придется не только обновлять шестнадцатеричное значение для этого стиля в CSS, но возможно также изменить все ссылки в разметке.

Если бы вместо этого использовалось class="callOut" (или что-либо аналогичное по смыслу), то пришлось бы делать гораздо меньше ручной работы.

Безумство классов

В CSS я придерживаюсь принципа «Лучше меньше, да лучше». Если можно назначить класс каждому элементу, то это еще не значит, что это следует делать.

В течение 300 часов моей работы по исправлению плохих CSS поставщиков я обнаружила огромное количество избыточных классов, которые вовсе там не требовались. Например, каждому элементу <label> был назначен класс class="label", а каждому элементу <form> был назначен class="form". Но в разметке имелся только один стиль для элемента <form>, который содержал только один стиль для элемента <label>.

form.form {    
    float: right;    
    margin: 0;    
    padding: 5px; 
} 
label.label {    
    clear: both;    
    float: left;    
    text-align: right;    
    width: 145px;
}

Хотя получившиеся CSS не были сами по себе ужасны (избыточны, но не ужасны), они приводили к путанице. Как проектировщик, наследующий CSS, я видела класс .form и предполагала, что в нем должны быть несколько другие стили, отличающиеся от стилей <form>, заданных другим значением класса. Охота на эти несуществующие стили заняла много моего времени.

Класс не обязателен для специфичности

Это лишь простой пример. Более подробный пример встреченного мной безумства классов, похоже, был следствием желания специфичности:

<div id="feature" class="tabs">    
    <ul class="tabs">       
        <li class="tabs"><a href="#newServices">New Services</a></li>     
        <li class="tabs"><a href="#newProducts">New Products</a></li>    
    </ul> 
</div>

Заметили, как class="tabs" применяется к каждому элементу в вышеприведенной разметке? Это приводило к следующей таблице CSS для адресации элементов списка:

div.tabs ul.tabs li.tabs {    
    float: left;    
    font-weight: bold;    
    padding: 3px; 
}

Более ясным и простым решением для адресации <li> было бы следующее:

#feature li {    
    float: left;    
    font-weight: bold;    
    padding: 3px;
}

Если значения классов не обязательны для адресации элементов стиля, не используйте их. Они утяжеляют разметку и CSS, а также значительно усложняют поиск в CSS.

Следует также отметить, что в последнем примере я ссылалась только на значение идентификатора в качестве селектора: #feature вместо div#feature. Добавлять div в селектор следует только в том случае, если это требуется для специфичности. Если не требуется, то такое добавление только увеличит CSS сверх необходимого, создавая дополнительную нагрузку для вас и ваших коллег. Кроме того, использование минимально возможного объявления облегчит последующее переопределение какого-либо стиля, если возникнет такая необходимость.

Несколько классов

Последний абзац может создать впечатление, что я не люблю большое количество классов. Хотя я несомненно не поддерживаю использование ненужных избыточных классов, я являюсь очень большим любителем поддержания компактности CSS путем использования множества классов для задания стилей элементов, которые имеют в целом общее описание, но требуются некоторые различия:

.announcement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    font-weight: bold;    
    padding: 10px;
}  
.newsAnnouncement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    float: right;    
    font-weight: bold;    
    padding: 10px; 
}

Эти два объявления идентичны, за исключением того, что .newsAnnouncement сдвигается вправо. Вместо повторения общей стилевой информации можно было бы написать следующее:

.announcement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    font-weight: bold;    
    padding: 10px;
}  
.floatR {    
    float:right; 
}

А затем в разметке назначить оба класса контенту для сводок новостей (news announcement):

<div class="announcement floatR">

Но подождите! Разве я только что не говорила о том, что семантические принципы именования лучше описательных? Конечно, говорила. Но для каждого правила есть исключения.

Да, .floatR — описательное название. Но в данной ситуации оно работает и достаточно универсально, чтобы можно было использовать его в других ситуациях, когда требуется несколько классов, поэтому именно такой подход часто используется моей группой.

Сгруппированные селекторы

Другая проблема, с которой мне пришлось бороться во время мучительного 300-часового сеанса, состояла в том, что идентичные объявления стилей были разбросаны по множеству таблиц стилей. Единственное различие между этими объявлениями было в том, что все они применялись к разным селекторам:

#productFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}  
#contactFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}
#serviceFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}

Это не только раздувало и так объемные файлы CSS, но еще и делало обслуживание кошмаром. Решение состоит в объединении этих селекторов, чтобы они ссылались на единое объявление стиля:

#productFeature, #contactFeature, #serviceFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}

Теперь, если потребуется обновить стиль, достаточно обновить только одно объявление, а не три.

Однострочный или многострочный формат?

Все примеры CSS в этой статье написаны с использованием многострочного формата, когда каждая пара «свойство-значение» находится в собственной строке. Это соглашение широко используется не только в файлах CSS, но также в книгах и статьях, посвященных CSS. Большинство людей считает, что такой формат более удобен для чтения, поэтому я использовала его в своей статье.

Однако для работы, которую я выполняю со своей группой, особенно в больших файлах CSS, я пишу мои стили в одной строке:

.alert {background: #fff; border: 1px solid #ff0; font-weight: bold; padding: 10px;}

Лично я считаю, что такой вид более удобен для чтения. Члены моей группы согласны с этим. Когда приходится работать с таким большим количеством строк CSS, многострочный формат становится слишком громоздким для просмотра. При записи всех стилей в одной строке просмотр становится легче.

Другие группы должны стараться быть последовательными. Определите, какой формат больше подходит для группы, и используйте его всегда.

Упорядочивать по алфавиту или нет?

Некоторые рекомендуют упорядочивать стилевые свойства по алфавиту в каждом объявлении, чтобы быстрее и проще находить свойства. Ранее я не уделяла этому особенного внимания, но столкнувшись с неразберихой в CSS поставщиков, могу признать, что такой подход к структурированию внутри объявлений стилей — хорошая идея.

Но я считаю, что более удобным является упорядочивание свойств не по алфавиту, а в соответствии с контекстом. Например, мне нравится сохранять все свойства полей вместе. Или в случае использования абсолютного позиционирования я группирую вместе следующие значения:

#logo {    
    border: 1px solid #000;    
    margin: 0;    
    padding: 0;    
    position: absolute;    
    top: 5px;    
    right: 3px; 
}

И опять, нельзя сказать, что это правильно или неправильно. Просто определите порядок свойств и придерживайтесь его. 

Подружитесь с сокращениями

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

Нулевые значения

Если задается нулевое значение, не обязательно указывать точки (а также проценты или другие единицы измерения):

margin: 2px 3px 0px 4px

становится

margin: 2px 3px 0 4px

Шестнадцатеричные цвета

Шестнадцатеричные цвета, состоящие из трех пар цифр, можно уменьшить, удалив по одной цифре из каждой пары:

color: #ff0000

становится

color: #f00

Свойства полей

Можно объединять такие свойства, как margin, padding и border, если значения для всех четырех сторон одинаковы:

padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px

становится

padding: 5px

Кроме того, если верхнее и нижнее или левое и правое значения свойств полей одинаковы, достаточно объявить два:

padding: 5px 10px 5px 10px

становится

padding: 5px 10px

Свойства шрифтов

Свойства шрифтов можно объединять:

font-style:italic; font-weight:bold; font-size: 90%; font-family: Arial, Helvetica, sans-serif;

становится

font: italic bold 90% Arial, Helvetica sans-serif

Свойства фона

Свойства фона также прекрасно объединяются:

background-color:#fff; background-image: url(logo.png); background-repeat: no-repeat; 
background-position: 0 10%;

становится

background: #f00 url(logo.png) no-repeat 0 10%

Необходимо обратить внимание на следующее. В последних двух коротких примерах свойств шрифтов и фона  порядок объявления значений свойств имеет значение. Не забудьте уточнить этот порядок в спецификации W3C.

Проверка, проверка, проверка

Хотя некоторые сообщества считают, что проверка CSS — это хорошее практическое правило, я думаю, что это абсолютно необходимо. Проверка дает шанс убедиться, что работа готова для совместного использования с другими членами группы, а также:

  • обеспечивает простоту разработки и устранения неполадок;
  • поддерживает согласованность в браузерах, как в текущий момент, так и в будущем;
  • обеспечивает ускоренную загрузку страниц;
  • является частью комплексной проверки специальных возможностей;
  • если написать правильно — значит не придется переделывать.

Я рекомендую использовать службу проверки CSS от W3C.

Средства сжатия

Если у вас и вашей группы имеются проблемы с размером файлов, загрузкой страниц и пропускной способностью (кто их не имел), то следует подумать о средстве сжатия для CSS. Эти средства могут делать все, от сокращения шестнадцатеричных значений цвета до удаления комментариев. Вот несколько средств, которые стоит рассмотреть.

Я не рекомендую использовать сжатие в промежуточных или разрабатываемых файлах, поскольку сжатие не только уменьшает размер файла, но также и затрудняет для группы возможность просмотра и работы с CSS. Все комментарии удаляются. Все пробелы удаляются. Больше нет файла CSS, с которым было легко работать. Выполняйте сжатие только на последнем этапе, когда работа с файлами завершена .

Верхушка айсберга

Рассмотренные в статье базовые принципы — только небольшая часть рекомендаций, призванных помочь вам и вашей группе CSS работать с удовольствием и более эффективно. Существует множество других рекомендаций, которым можно следовать, чтобы сделать CSS еще лучше. Если вы серьезно заинтересовались, я рекомендую продолжить и перейти к чтению следующих статей.

Следуйте золотому правилу

Независимо от того, ведется ли работа во внутренней группе, или с поставщиками и субподрядчиками, или одним человеком как группой в одном лице, приведенные здесь рекомендации по CSS помогут установить основные правила, чтобы научиться хорошо работать в группе CSS, а также сохранить время и нервы.

Просто вернитесь в дошкольные годы и вспомните золотое правило: «Делай в своих CSS то, что хотел бы, чтобы делали другие».