Сложные CSS селекторы, содержащие класс и ID элементов.

Перевод статьи:  Multiple class ID selectors.
Автор:  Chris Coyier.

Взгляните на приведенные ниже два CSS селектора. Сможете ли вы определить их функциональное отличие:

#header.callout { }
#header .callout { }

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

Верхний селектор #header.callout имеет следующую аннотацию:

Выбирает элемент, с идентификатором header и CSS классом callout.

Нижнему селектору #header .callout соответствует другое определение:

Выбирает все элементы, имеющие CSS класс callout, которые являются дочерними по отношению к элементу с идентификатором header
Изображение.

Надеюсь, что эта иллюстрация развеет все ваши сомнения.

Возможные комбинации имен классов и идентификаторов в CSS селекторах.

Особенно полезной с практической точки зрения является возможность составления селекторов из имен классов и идентификаторов без пробелов между ними.

Комбинация из ID и имени класса.

Такой вид CSS селектора рассмотрен выше. Приведем лишь еще один наглядный пример:

<h1 id="id-name" class="class-name">Текст этого заголовка должен быть красным.</h1>

и соответствующий этому элементу CSS код:

#id-name.class-name {color: red;}

Вариант из нескольких имен классов.

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

<h1 class="first-class-name second-class-name">Используем несколько имен классов</h1>

для выбора этого элемента используем такой селектор:

.first-class-name.second-class-name {color: red;}

Сложные комбинации.

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

.snippet#header.coding.red {color: red;}

Пример использования.

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

#header {color: blue;}
#header.override {color: red;}

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

.override {color: red !important}

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

Селекторы, состоящие из нескольких имен классов, являются более популярными и полезными. Хочется обратить особое внимание на их применение в так называемом объектно ориентированном CSS стилевом оформлении документов, которое является предметом различных споров. К примеру, у вас имеется некоторое количество блоков <div>, и для их оформления вы применяете несколько описательных имен классов:

<div class="red border box"></div>
<div class="blue border box"></div>
<div class="green border box"></div>
<div class="red box"></div>
<div class="blue box"></div>
<div class="green box"></div>
<div class="border box"></div>

Все присутствующие блоки используют класс box, который может содержать свойства, определяющие размерность элемента или текстуру его фона, общие для всех блоков. Кроме того, некоторые из них содержат классы с именами цветов, которые нужны для определения цветовой палитры, используемой для оформления элементов блока (текста, фона). К примеру, класс green может устанавливать зеленый фон элемента и светло-зеленый шрифт текста внутри него. Так же в примере имеются блоки, содержащие имя класса border, который, видимо, отвечает за отображение границ элемента. Те из них, у которых нет класса border, границ не имеют.

Теперь давайте определим, указанные в HTML разметке CSS классы:

.box {width: 100px; float: left; margin: 0 10px 10px 0;}
.red {color: red; background: pink;}
.blue {color: blue; background: light-blue;}
.green {color: green; background: light-green;}
.border {border: 5px solid black;}

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

.red.border {border-color: #900;}
Изображение.

Применив такое правило, красные блоки будут иметь другой цвет границ так как содержат оба класса, определенные в селекторе — red и border. На этой демо странице можно увидеть больше примеров.

Специфичность рассмотренных селекторов.

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

Поддержка браузерами.

Все новые версии популярных браузеров, включая IE7, без проблем поддерживают такие комбинации CSS селекторов. Чего не скажешь о IE6, который, при использовании сложного селектора, производит отбор элементов только по последнему имени класса, игнорируя предыдущие. То есть, при использовании селектора .red.border в этом браузере будут выбраны блоки только с классом .border, что полностью разрушает идею рассматриваемого в статье подхода. Но если поддержка IE6 для вас привычное дело, то вы с легкостью справитесь с подобными ситуациями, обойдя их с помощью CSS хаков и условных комментариев.

* Примечание переводчика.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *