Статьи

Золотые правила написания чистого CSS

Ниже приводится выдержка из нашей книги CSS Master , написанной Тиффани Браун. Копии продаются в магазинах по всему миру, или вы можете купить их в электронном виде здесь .

Золотые правила написания чистого CSS

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

  • Избегайте глобальных и элементных селекторов
  • Опускать слишком конкретные селекторы
  • Используйте имена семантических классов
  • Не привязывайте CSS слишком близко к структуре разметки

Давайте посмотрим на это один за другим.

Избегайте глобальных селекторов

Глобальные селекторы включают универсальный селектор ( * ), селекторы элементов, такие как p , button и h1 , и селекторы атрибутов, такие как [type=checkbox] . Объявления стиля, применяемые к этим селекторам, будут применяться к каждому такому элементу на сайте. Вот пример:

 button { background: #FFC107; border: 1px outset #FF9800; display: block; font: bold 16px / 1.5 sans-serif; margin: 1rem auto; width: 50%; padding: .5rem; } 

Это кажется достаточно безобидным. Но что, если мы хотим создать кнопку, стилизованную по-другому? Давайте .close кнопку .close , которая будет использоваться для закрытия диалоговых модулей:

 <section class="dialog"> <button type="button" class="close">Close</button> </section> 
Примечание: почему бы не использовать dialog?

Здесь мы используем section вместо элемента dialog потому что поддержка dialog ограничена браузерами на основе Blink, такими как Chrome / Chromium, Opera и Yandex.

Теперь нам нужно написать CSS, чтобы переопределить каждую строку, которую мы не хотим наследовать из набора правил button :

 .close { background: #e00; border: 2px solid #fff; color: #fff; display: inline-block; margin: 0; font-size: 12px; font-weight: normal; line-height: 1; padding: 5px; border-radius: 100px; width: auto; } 

Нам все еще нужно было бы использовать многие из этих объявлений, чтобы переопределить настройки браузера по умолчанию. Но что если мы .default наши стили .default класс .default ? Затем мы можем удалить объявления display , font-weight , line-height , margin , padding и width из нашего .close правил .close . Это уменьшение на 23%:

 .default { background: #FFC107; border: 1px outset #FF9800; display: block; font: bold 16px / 1.5 sans-serif; margin: 1rem auto; width: 50%; padding: .5rem; } .close { background: #e00; border: 2px solid #fff; color: #fff; font-size: 12px; padding: 5px; border-radius: 100px; } 

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

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

Избегайте чрезмерно специфических селекторов

Сохранение низкой специфичности в ваших селекторах является одним из ключей к созданию легкого, многократно используемого и поддерживаемого CSS. Как вы помните по специфичности, селектор типа имеет специфичность 0,0,1. Селекторы классов, с другой стороны, имеют специфичность 0,1,0:

 /* Specificity of 0,0,1 */ p { color: #222; font-size: 12px; } /* Specificity of 0,1,0 */ .error { color: #a00; } 

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

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

Не цепочка классов

Также избегайте цепочки селекторов классов. Селекторы типа .message.warning имеют специфичность 0,2,0. Более высокая специфичность означает, что их трудно переопределить, плюс цепочка часто вызывает побочные эффекты. Вот пример:

 message { background: #eee; border: 2px solid #333; border-radius: 1em; padding: 1em; } .message.error { background: #f30; color: #fff; } .error { background: #ff0; border-color: #fc0; } 

Использование <p class="message"> с этим CSS дает нам красивую серую рамку с темно-серой рамкой, как показано на рисунке 2.1:

Рисунок 2.1. Визуальный эффект нашего селектора .message

Использование <p class="message error"> , однако, дает нам фон .message.error и границу .error показанную на рисунке 2.2:

Рисунок 2.2. Визуальный результат использования .message.error в качестве селектора

Единственный способ переопределить цепочечный селектор класса — использовать еще более конкретный селектор. Чтобы избавиться от желтой границы, нам нужно добавить в цепочку имя класса или селектор типа: .message.warning.exception или div.message.warning . Вместо этого целесообразнее создать новый класс. Если вы обнаружите, что селекторы цепочки, вернитесь к чертежной доске. Либо в дизайне есть несоответствия, либо вы преждевременно цепляетесь, пытаясь предотвратить проблемы, которых у вас нет. Исправьте эти проблемы. Вы избавитесь от проблем, связанных с техническим обслуживанием, и повторного использования, которое вы получите.

Избегайте использования селекторов id

Поскольку вы можете иметь только один элемент для каждого id в документе, наборы правил, которые используют селекторы id , трудно переназначить. Обычно это включает использование списка селекторов id ; например, #sidebar-features и #sidebar-sports .

Идентификаторы также имеют высокую степень специфичности, поэтому нам понадобятся более длинные селекторы для переопределения объявлений. В следующем CSS мы должны использовать #sidebar.sports и #sidebar.local чтобы переопределить цвет фона #sidebar :

 #sidebar { float: right; width: 25%; background: #eee; } #sidebar.sports { background: #d5e3ff; } #sidebar.local { background: #ffcccc; } 

Переключение на селектор классов, например .sidebar , позволяет упростить нашу цепочку селекторов:

 sidebar { float: right; width: 25%; background: #eee; } .sports { background: #d5e3ff; } .local { background: #ffcccc; } 

Помимо экономии нескольких байтов, наши .sports и .local теперь могут быть добавлены к другим элементам.

Использование селектора атрибута, такого как [id=sidebar] позволяет нам обойти более высокую специфичность идентификатора. Хотя в нем отсутствует возможность повторного использования селектора класса, низкая специфичность означает, что мы можем избежать цепочки селекторов.

Примечание: когда полезна высокая специфичность селекторов id

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

Наконец, давайте поговорим о селекторах, таких как #main article.sports table#stats tr:nth-child(even) td:last-child . Это не только абсурдно долго, но со спецификой 2,3,4, он также не может быть использован повторно. Сколько возможных экземпляров этого селектора может быть в вашей разметке? Давайте сделаем это лучше. Мы можем немедленно обрезать наш селектор до #stats tr:nth-child(even) td:last-child . Это достаточно конкретно, чтобы сделать работу. Тем не менее, гораздо лучший подход — как для повторного использования, так и для минимизации количества байтов — это использовать вместо этого имя класса.

Примечание: симптом вложенности препроцессора

Чрезмерно специфичные селекторы часто являются результатом слишком большого вложения препроцессора.

Используйте имена семантических классов

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

Вот примеры того, что не нужно делать: .red-text , .blue-button , .border-4px , .margin10px . Что с ними не так? Они слишком тесно связаны с существующим выбором дизайна. Использование class="red-text" для разметки сообщения об ошибке работает. Но что произойдет, если изменения в дизайне и сообщения об ошибках станут черным текстом внутри оранжевых рамок? Теперь ваше имя класса неточно, что затрудняет понимание вами и вашими коллегами того, что происходит в коде.

В этом случае лучше выбрать имя класса, например .alert , .error или .message-error . Эти имена указывают, как должен использоваться класс, и тип содержимого (сообщения об ошибках), на который они влияют. Для имен классов, которые определяют макет страницы, добавьте префикс, такой как layout- , grid- , col- или просто l- чтобы сразу увидеть, что они делают. Раздел о методологии БЭМ позже описывает процесс для этого.

Избегайте привязки CSS близко к разметке

Вы, вероятно, использовали селекторы потомков или потомков в своем коде. Дочерние селекторы следуют шаблону E > F где F — элемент, а E — его непосредственный родитель. Например, article > h1 влияет на элемент h1 в <article><h1>Advanced CSS</h1></article> , но не на элемент h1 в <article><section><h1>Advanced CSS</h1></section></article> . Селектор потомков, с другой стороны, следует шаблону EF где F — элемент, а E — предок. Чтобы использовать наш предыдущий пример, article h1 выбирает элемент h1 в обоих случаях.

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

Поднимите руку, если вы когда-либо испытывали следующее. Вы разработали несколько шаблонов для клиента, и ваш CSS использует селекторы потомков и потомков в нескольких местах. Большинство этих потомков и потомков также являются селекторами элементов, поэтому такие селекторы, как .promo > h2 и .media h3 встречаются по всему вашему коду. Ваш клиент также нанял консультанта по SEO, который рассмотрел вашу разметку и предложил вам изменить элементы h2 и h3 элементы h1 и h2 . Проблема в том, что мы также должны изменить наш CSS.

Еще раз, селекторы класса показывают свое преимущество. Использование .promo > .headline или .media .title (или, проще, .promo-headline и .media-title ) позволяет нам изменять нашу разметку без необходимости изменения CSS.

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

Примечание: более архитектурно обоснованные правила CSS

Филип Уолтон обсуждает эти и другие эти правила в своей статье «Архитектура CSS». Я также рекомендую сайт CSS Guidelines Гарри Робертса и пост Николаса Галлахера « О семантике HTML и архитектуре переднего плана», чтобы больше узнать об архитектуре CSS.

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