Permalink
Switch branches/tags
Nothing to show
Find file
c925a84 Jun 9, 2017
@iamstarkov @Ser-Gen @barbagrigia @poporul
533 lines (348 sloc) 50.9 KB

Основные правила и принципы написания CSS

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

  • Легко поддерживаемые файлы стилей
  • Прозрачность и читаемость кода
  • Масштабируемость стилей

Несколько техник помогут нам достичь этих целей.

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

Содержание


Анатомия CSS-документа

Мы всегда должны стараться соблюдать принятое форматирование. Это означает согласованные комментарии, синтаксис и соглашение об именовании.

Общие моменты

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

Я предпочитаю отступы в четыре пробела и писать многострочный CSS.

Один файл или много файлов

Некоторые предпочитают работать с одиночными, большими файлами. Это хорошо и при следовании данному руководству у вас не прибавится проблем. Начав использовать Sass, я начал разбивать мои стили на множество маленьких, подключаемых через include. Это тоже хорошо… Как бы там ни было, правила и рекомендации, приведённые ниже, применимы к обоим способам. Единственное замечание относится к «Оглавлению» и «Названиям секций». Продолжайте читать, чтобы узнать подробности.

Оглавление

В начале CSS файла я храню таблицу содержимого, которая уточняет какие секции содержатся в этом файле, например:

/*------------------------------------*\
    $CONTENTS
\*------------------------------------*/
/**
 * CONTENTS............You’re reading it!
 * RESET...............Set our reset defaults
 * FONT-FACE...........Import brand font files
 */

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

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

Названия секций

Оглавление будет бесполезно пока не будет соотноситься с названиями секций. Оформляйте секцию таким способом:

/*------------------------------------*\
    $RESET
\*------------------------------------*/

Знак $ префиксно дополняет название секции, позволяя искать по файлу такой шаблон $[НАЗВАНИЕ-СЕКЦИИ] и, таким образом, производить поиск только по названиям секций.

Работая с большим файлом стилей, оставляейте отступ в пять строк между секциями, вот так:

/*------------------------------------*\
    $RESET
\*------------------------------------*/
[Our
reset
styles]
 
 
 
 
 
/*------------------------------------*\
    $FONT-FACE
\*------------------------------------*/

Этот участок пустого пространство легко и быстро бросается в глаза при пролистывании большого файла.

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

Организация правил

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

Порядок правильно организованного файла стилей похож на это:

  1. Reset – сброс, платформа для написания кода стилей.
  2. Элементыh1, ul и подобные без указания классов.
  3. Объекты и абстракции — общие конструкции без дизайна.
  4. Компоненты – компоненты, построенные на объектах и их расширениях.
  5. Полезные стили – состояния ошибок и другое.

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

Для дальнейшего чтения по этой теме, я не могу отозваться о книге SMACSS от Джонатана Снука настолько хорошо, насколько она того заслуживает.

Анатомия CSS-правила

[Селектор] {
    [Свойство]:[Значение]
    [<-   Объявление  ->]
}    

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

  • Дефис как разделитель (Исключая БЭМ запись, смотрите ниже)
  • Отступ в 4 пробела
  • Многострочность
  • Свойства сортируются в порядке релевантности (НЕ в алфавитном)
  • Выравнивайте свойства с вендорными префиксами так, чтобы их значения были друг под другом.
  • Используйте отступы в стилях, чтобы отразить структуру HTML.
  • Всегда заканчивайте объявление знаком точки с запятой

И сразу пример:

.widget{
    padding:10px;
    border:1px solid #BADA55;
    background-color:#C0FFEE;
    -webkit-border-radius:4px;
       -moz-border-radius:4px;
            border-radius:4px;
}
    .widget-heading{
        font-size:1.5rem;
        line-height:1;
        font-weight:bold;
        color:#BADA55;
        margin-right:-10px;
        margin-left: -10px;
        padding:0.25em;
    }

Наглядно видно, что .widget-heading является дочерним элементом .widget, так как .widget-heading имеет дополнительный отступ относительно селектора .widget. Эту полезную информацию разработчики могут считать просто взглянув на отступы в наших стилях.

Также мы видим, что объявления селектора .widget-heading отсортированы в порядке релевантности; .widget-heading вероятнее всего текстовый элемент, поэтому мы начинаем правило с типографских свойств, за которыми уже следуют все остальные.

Единственное исключение в многострочном CSS может быть в таком случае:

.t10    { width:10% }
.t20    { width:20% }
.t25    { width:25% }       /* 1/4 */
.t30    { width:30% }
.t33    { width:33.333% }   /* 1/3 */
.t40    { width:40% }
.t50    { width:50% }       /* 1/2 */
.t60    { width:60% }
.t66    { width:66.666% }   /* 2/3 */
.t70    { width:70% }
.t75    { width:75% }       /* 3/4*/
.t80    { width:80% }
.t90    { width:90% }

В этом примере (из сеточной системы inuit.css) гораздо больше смысла использовать однострочные правила.

Соглашения об именовании

В большинстве случаев я использую дефис как разделитель слов в классах (например .foo-bar, не .foo_bar и не .fooBar), но в некоторых случаях я использую БЭМ-запись.

БЭМ — методология именования и категоризации CSS селекторов для приведения их в чёткий порядок, придания прозрачности и информативности.

Соглашение об именовании выражается следующим шаблоном:

.block{}
.block__element{}
.block--modifier{}
  • .block представляет собой наивысший уровень абстракции или компонента.
  • .block__element является вложенным элементом .block, формирующим .block как сущность.
  • .block--modifier — класс отражающий другое состояние или версию .block.

Аналогия, иллюстрирующая работу БЭМ, может быть такой:

.person{}
.person--woman{}
    .person__hand{}
    .person__hand--left{}
    .person__hand--right{}

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

Теперь мы можем создавать селекторы, опираясь на базовые объекты и также без проблем понимаем, что делает каждый конкретный селектор; является ли он частью компонента (__) или же модификацией (--)?

Итак, .page-wrapper является отдельным селектором; он не формирует часть компонента и, значит, является валидным селектором. В противовес этому, селектор .widget-heading относится к компоненту; он является дочерним элементом .widget и поэтому мы вынуждены переименовать этот класс в .widget__heading.

БЭМ непригляднее и перегруженней, но, тем не менее, он предоставляет огромные возможности, с помощью которых мы можем определить назначение и отношения элементов просто посмотрев на их классы. Также, БЭМ обычно сжимается c помощью gzip, после использования минификаторов, которые первоклассно работают с повторениями.

Независимо от того, используете вы БЭМ или нет, всегда заботьтесь о грамотном именовании классов; классы должны быть короткими, насколько это возможно, но настолько длинными, насколько это необходимо. Убедитесь, что абстракции имеют очень общие классы (например .ui-list, .media) для возможного переиспользования. Расширения абстракций должны иметь гораздо более конкретные классы (например .user-avatar-link). Не беспокойтесь о длинных классах; gzip выполнит свою работу потрясающе хорошо.

Классы в HTML

Для большей читаемости разделяйте классы в разметке двумя (2) пробелами:

<div class="foo--bar  bar__baz">

Увеличенные отступы между классами позволят легко вычленять отдельные классы.

JS-классы

Никогда не используйте в JavaScript-логике обычные, уже используемые для стилизации классы. Связывание логики скриптов с оформлением ведёт к тому, что мы не сможем использовать одно без другого.

Если вам требуется привязать к вёрстке какую-то логику, используйте специальный JS-класс — обычный класс, дополненный префиксом .js-, например .js-toggle, .js-drag-and-drop. Данный приём позволяет добавлять JS- и CSS-классы, без создания самому себе проблем в будущем, а также разделяет логику поведения и оформление страницы друг от друга.

<th class="is-sortable  js-is-sortable">
</th>

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

Интернационализация

Несмотря на то, что я британский разработчик и привык писать colour вместо color, считаю, что для улучшения однородности лучше использовать американский английский при написании CSS. CSS, как и другие (если не все) языки, написан на американском английском, так что сочетание color:red; с классами .colour-picker{} вредит однородности кода. Я ранее предлагал и отстаивал написание селекторов на двух языках, например:

.color-picker,
.colour-picker{
}

Тем не менее, работая недавно над очень большим Sass-проектом, в котором было множество colour-переменных (например, $brand-color, $highlight-color и т.д.), я осознал, что поддержка двух версий каждой переменной очень скоро становится утомительна. Это также означает в два раза больше работы с такими вещами, как поиск и замена.

Для однородности всегда называйте классы и переменные на той локализации языка, которая в нём принята.

Комментарии

Я использую комментарии в стиле docBlock, которые я ограничиваю в 80 символов:

/**
 * Пример комментария в стиле docBlock
 *
 * Более длинное описание комментария, описывающего код в больших
 * подробностях. Комментарии ограничиваются в 80 символов.
 * 
 * Можно вставлять разметку в комментарии. Делается это так:
 * 
   <div class=foo>
       <p>Lorem</p>
   </div>
 * 
 * Разметка префиксно не дополняется звездочками, чтобы оставить возможность
 * легкого копипаста.
 * 
 */

Вы должны документировать и комментировать так много, насколько возможно; всё, что кажется вам прозрачным и говорящим за себя, может не быть таковым для другого разработчика. Пишите кусок кода и сразу после этого объясняйте его.

Комментарии на стероидах

Существуют несколько продвинутых техник, связанных с комментариями:

  • Квази-селекторы
  • Теги в коде
  • Ссылка на расширяемый компонент

Квази-селекторы

Вы никогда не должны перегружать селектор; скажем так, вы никогда не должны писать ul.nav{}, если вы можете написать просто .nav{}. Перегрузка селекторов приводит к уменьшению производительности селекторов (увеличению времени рендеринга страницы), исключает возможность потенциального переиспользования селектора для элемента другого типа и увеличивает специфичность селектора. Это все те вещи, которые должны избегаться при любых условиях.

Иногда бывает полезно сообщить следующему разработчику, в каком контексте вы собираетесь использовать селектор. Давайте рассмотрим .product-page. Этот класс выглядит так, как будто должен использоваться с корневыми элементами, такими как html и body, но глядя только на .product-page нет возможности утверждать наверняка, с каким именно.

Используя смешанные селекторы (например, комментирование первого простого селектора по типу), мы можем сообщить с каким элементом следует использовать этот класс:

/*html*/.product-page{}

В этом примере мы чётко видим к какому элементу принадлежит данный класс, без проблем со специфичностью и переиспользованием этого кода.

Другие примеры могут быть такими:

/*ol*/.breadcrumb{}
/*p*/.intro{}
/*ul*/.image-thumbs{}

Теперь мы можем увидеть к чему применён каждый класс, не увеличивая специфичность селектора.

Теги в коде

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

/**
 * ^navigation ^lists
 */
.nav{}

/**
 * ^grids ^lists ^tables
 */
.matrix{}

Теги позволяют разработчикам находить сниппеты поиском по названию тега. Если разработчику понадобится поработать со списками, он может начать искать ^lists и найдёт объекты .nav и .matrix (и, возможно, больше).

Ссылки между объектом и его расширением

Используя методы OOCSS, вы часто будете иметь два участка кода (один — скелет приложения (объект) и второй будет его кожей (расширение)), при этом сильно связанных, но, как часто бывает, находящихся в разных файлах. Для установления чёткой связи между объектом и его расширением мы применяем ссылки между объектом и его расширением. Данные ссылки являются такими комментариями:

В вашем основном файле стилей:

/**
 * Extend `.foo` in theme.css
 * (Дополнен классом `.foo` в theme.css)
 */
 .foo {}

В вашем файле стилей темы:

/**
 * Extends `.foo` in base.css
 * (Дополняет класс `.foo` из base.css)
 */
 .bar{}

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


Напиcание CSS

Предыдущая часть раскрывает, как мы структурируем и форматируем наш CSS; здесь существуют более-менее чёткие правила.

Следущая часть будет немного более теоретической и повествует о наших способах мышления и подходах.

Создание новых компонентов

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

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

OOCSS

Я использую OOCSS подход; Я разделяю компоненты на структуру (объекты) и оформление (расширения). Как аналогию (не пример) можно рассмотреть следующее:

.room{}

.room--kitchen{}
.room--bedroom{}
.room--bathroom{}

Мы располагаем комнатами нескольких типов, но все комнаты имеют похожие свойства; в каждой комнате есть пол, потолок, стены и двери. Мы можем обобщить эту информацию в общем классе .room{}. Тем не менее, у нас есть специальные отличающиеся друг от друга типы комнат; кухня должна иметь плитку на полу, спальня — ковёр; в ванной не должно быть окна, а в спальне, напротив, должно. В каждой комнате скорее всего стены покрашены в свой цвет. OOCSS учит нас абстрагировать похожие свойства в базовый объект и в дальнейшем дополнять его с помощью расширяющих классов для добавления особенных качеств.

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

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

Разметка

Все компоненты должны быть полностью независимы от ширины; они должны оставаться резиновыми и их ширина должна контролироваться их обёрткой или системой модульных сеток.

Высота никогда не должна назначаться элементам. Высота применяется только на сущности, имевшие размеры до того, как попали на сайт (например, картинки и спрайты). Никогда не устанавливайте высоту на p, ul, div, ни на что. Часто вы можете добиться желаемого эффекта при помощи гораздо более гибкого line-height.

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

Вы никогда не должны применять никаких стилей на ячейку сетки, так как они нужны лишь для разметки. Применяйте стили только к содержимому ячейки. Никогда, ни при каких обстоятельствах не применяйте свойства меняющие поведение box-model к ячейкам сетки.

Единицы измерения

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

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

Размеры шрифтов я устанавливаю в rem c запасным решением с использованием пикселей. Этот метод предоставляет доступность контента как с em и уверенность при использовании пикселей. Вот простой Sass-миксин для одновременной работы с пикселями и rem (вы должны определить переменную $base-font-size ранее в стилях):

@mixin font-size($font-size){
    font-size:$font-size +px;
    font-size:$font-size / $base-font-size +rem;
}

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

Размер текста

Я составил список классов (похожих на модульную сетку) для задания размера текста. Эти классы могут быть использованы стилизации текста в двухцепочечной иерархии. Моя статья «Pragmatic, practical font-sizing in CSS» расскажет вам, как это работает.

Сокращённая запись

Сокращённую запись следует использовать с осторожностью.

Это может показаться заманчивым использовать правила похожие на background: red;, но делая это, мы на самом деле говорим: «Я хочу, чтобы фоном не было скролящейся, находящейся сверху-слева и повторяющейся по горизонтали и вертикали картинки и чтобы цвет фона был красный». В девяти случаях из десяти это не вызовет никаких проблем, но в 10% обязательно доставит достаточно неприятностей, чтобы не использовать сокращенные записи. Вместо этого используйте background-color: red;.

Например, ситуация с правилом margin: 0; — оно ясное и короткое, но черезчур точное. Если вы на самом деле хотите воздействовать на нижний отступ элемента, то гораздо более подходяще будет использовать margin-bottom: 0;.

Старайтесь сохранять чёткое представление о свойствах, которые вы устанавливаете и следите за тем, чтобы случайно не сбросить свойства других элементов, используя сокращенную запись. Например, если вы хотите сбросить нижний отступ, то нет никакой необходимости в сбрасывании всех отступов с помощью margin: 0;.

Сокращённая запись хороша, но ей легко злоупотреблять.

Идентификаторы

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

НИКОГДА не используйте идентификаторы в CSS.

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

Преимущество классов в их многоразовости (даже если мы не хотим, мы можем) и у них есть хорошая, низкая специфичность. Специфичность это один из скорейших путей к преодолению проблем в проектах и позволяет всё время сокращать их количество, что является необходимым. Идентификаторы в 255 раз более специфичны, чем классы, так что больше не используйте их в CSS никогда.

Селекторы

Сохраняйте селекторы короткими, эффективными и переносимыми.

Тяжелые, глубоко вложенные селекторы никуда не годятся по ряду причин. Например возьмем .sidebar h3 span {}. Этот селектор сильно привязан к существующей разметке и поэтому нет возможности переместить span из h3 и из .sidebar, следовательно, нет возможности обеспечить поддержку стилей на должном уровне.

Слишком длинные селекторы также вызывают проблемы производительности; чем больше проверок в селекторе (например, селектор .sidebar h3 span имеет три проверки, а .content ul p a — четыре), тем больше работы выполняет браузер.

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

Селекторы в основном должны быть короткими (например, состоящими из одного класса), но имена классов должны быть настолько длинными, насколько это требуется. Класс .user-avatar намного лучше, чем .usr-avt.

Запомните: Классы на самом деле ни семантичны, ни не семантичны; они могут использоваться рационально или нерационально! Перестаньте беспокоиться о «семантике» имён классов и выберите что-нибудь рациональное и безопасное в будущем.

Перенасыщенные селекторы

Как говорилось выше, увидеть специфичный селектор — всегда плохой знак.

Перенасыщенный (гиперспецифичный) селектор это такой, как div.promo. Скорее всего, мы можем достичь тот же самый эффект, используя лишь .promo. Конечно, иногда мы хотим указать зависимость класса от элемента (например, если у вас есть общий класс .error, который должен выглядеть по разному при разных элементах (например, .error { color: red; } div.error { padding: 14px; })), но по возможности избегайте этого, где это только возможно.

Другим примером слишком перенасыщенного селектора может быть ul.nav li a {}. Как описано выше мы сразу можем выкинуть ul, и так как мы знаем, что .nav это список, то ссылка будет вложена только в li, поэтому мы можем сократить ul.nav li a {} до .nav a.

Производительность селекторов

Хоть это и правда, что браузеры только улучшают свои показатели в скорости рендеринга CSS, эффективность — это то, на чём мы можем быть сфокусированы всегда. Короткие, не вложенные селекторы, избежание универсального (* {}) селектора, как основного, и избежание больших комбинаций CSS3-селекторов должны помочь обойти проблемы производительности.

Последовательность CSS-селекторов

Вместо использования селекторов, спускающихся по всему DOM-дереву, чаще удобнее добавить требуемому элементу класс. Давайте рассмотрим конкретную ситуацию на примере .header ul{}

Давайте представим, что ul действительно главная навигация на вашем сайте. Этот элемент находится в шапке сайта, как вы и ожидаете, и при этом не повторяется; .header ul{} будет работать, но он не идеален и не рекомендуем. Этот селектор небезопасен в будущем и, конечно, недостаточно точен. Проблема станет очевидна так скоро, как вы добавите ещё один ul в шапку сайта — новый элемент унаследует все стили нашего главного меню, и шансы, что мы так и задумали, весьма невелики. Это приведёт к вынужденному рефакторингу большого количества кода или отмене большинства стилей для второго ul, чтобы уничтожить последствия недостаточно специфичного селектора.

Составляющие селектора должны отвечать причинам стилизации чего-либо; спросите себя «Я пишу этот селектор именно, потому что ul вложен в .header или из-за того, что этот элемент — это главное меню на моём сайте?». Ответ опреляет правильный селектор.

Убедитесь, что ключевые элементы селектора не являются простыми селекторами элемента/типа или классами объекта/абстракции. Вы никогда не должны писать селекторы похожие на .sidebar ul{} или .footer .media{} в вашем файле стилей темы.

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

Для полного объяснения прочитайте мою статью Shoot to kill; CSS selector intent

!important

Допустимо использовать !important только на вспомогательных классах. Превентивно добавлять !important удобно и полезно, например, если вы знаете, что селектор .error { color: red !important; } всегда должен нуждаться в наибольшем приоритете.

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

Магические числа и абсолютные значения

Магическое число — число используемое лишь потому, что «это просто работает». Это порочная практика, так как очень редко она работает по какой-либо реальной причине и обычно достаточно недальновидна, негибка и причина появления самого числа вероятнее всего забудется. Магические числа устраняют симптомы, но не никак не влияют на проблему.

Например, использование .dropdown-nav li:hover ul { top: 37px; }, чтобы расположить выпадающее меню внизу навигации не принесёт ничего хорошего, так как 37px магическое число. Оно работает только потому, что в этом конретном сценарии элемент .dropdown-nav оказался высотой в 37 пикселей.

Вместо этого мы должны использовать .dropdown-nav li:hover ul { top: 100%; }, что означает: вне зависимости какой высоты будет меню dropdown-nav, выпадающее всегда будет сдвинуто на 100% от верхней границы родителя.

Каждый раз, когда вы жёстко задаёте число, подумайте дважды; если вы можете избежать этого — избегайте, например, используя ключевые слова или синонимы (top: 100%; для того, чтобы сдвинуть на 100% от верха) или — даже лучше — не используя никаких единиц измерений.

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

Стили в условных комментариях

Использования отдельных файлов стилей для IE, по большому счёту, можно избежать. Исключением может быть необходимость восполнить вопиющие недостатки поддержки различных свойств (например, PNG с альфа–каналом в IE6).

Главное правило: вся разметка и box-model правила могут и будут работать без дополнительных файлов стилей, если вы отрефакторите и переработаете ваш CSS. Это означает, что мы никогда не будем рады, если увидим <!--[if IE 7]> element{ margin-left:-9px; } < ![endif]--> или любой подобный CSS, используемый лишь для того, чтобы «заставить что-то работать правильно».

Отладка

Если вы столкнулись с проблемой в CSS, то удаляйте куски кода, до того как начать добавлять новые правила в попытке решить проблему. Проблема кроется в уже написанном CSS, написать ещё больше стилей — не самое верное решение!

Удаляйте куски разметки и стилей, пока проблема не исчезнет, затем определите, в какую часть кода закралась проблема.

Это бывает достаточно удобно добавить overflow: hidden; нужному элементу, чтобы избавиться от результатов кривой вёрстки, но overflow сам по себе вряд ли был проблемой; исправляйте проблему, а не её симптомы.

Препроцессоры

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

.header{}
.header .site-nav{}
.header .site-nav li{}
.header .site-nav li a{}

Это было бы полностью избыточно в нормальном CSS, следовательно, следущий Sass-код будет плох:

.header{
    .site-nav{
        li{
            a{}
        }
    }
}

Иcпользуя Sass, пишите это так:

.header{}
.site-nav{
    li{}
    a{}
}