Семнадцатый урок. Селекторы CSS

При создании CSS-классов мы в основном пользовались селектором тэга и универсальным селектором *. На самом деле в CSS есть и другие селекторы, которые во многих случаях упрощают верстку.

Селектор тэга самый простой — он непосредственно влияет на тэги. Определяется он вот такой схемой (E — это любой тэг):

E { стиль }

Пример:

p { color: red; }

Цвет всех тэгов P станет красным.


Идентификатор элемента обозначается через атрибут тэга id, который является уникальным на странице, то есть не должен повторяться <div id="myblock">. В CSS-коде идентификатор отмечается с символом #:

#ID { стиль }

#myblock { color: red; }

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


Селектор класса мы уже вовсю используем:

E.класс { стиль }
p.red { color: red; }

Сработает только там, где у тэга P указан класс red: <p class="red">.


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

*.класс { стиль }
.класс { стиль }

Например:

.red { color: red; }

Будет работать с любым тэгом, у которого указан класс red: <div class="red">


Вложенные селекторы применяются ко вложенным элементам.

E F { стиль }

Например у нас есть разметка:

<div>
	<h1>Заголовок 1</h1>
</div>

<h1>Заголовок 2</h1>

То есть первый блок H1 вложен в DIV, а второй вне его. Правило:

div h1 { color: red; }

Сделает красным цветом текст только первого заголовка. Второй не изменится.

Более распространен вариант, когда у контейнера указывается уточняющий класс.
div.block h1 { color: red; }
<div class="block">
	<h1>Заголовок 1</h1>
</div>

<h1>Заголовок 2</h1>

<div class="block2">
	<h1>Заголовок 3</h1>
</div>

То есть стиль применится к H1 который находится внутри div.block.

Данное сокращение очень часто встречается у верстальщиков и означает тэг/элемент с указанным классом: <div class="block">

Дочерние селекторы влияют на непосредственных потомков контейнера. Например вот такая разметка:

<div class="block">
	<h1>Заголовок 1</h1>
	
	<div>
		<h1>Заголовок 2</h1>
	</div>

</div>

То есть первый заголовок является непосредственным потомком div.block, а второй таковым уже не является — у него уже другой родитель.

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

E > F { стиль }
div.block > h1 { color: red; }

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

div.block > div > h1 { color: red; }

То есть браузер ищет div.block, в нём непосредственного потомка DIV, и уже в нём H1.


Соседние селекторы — это такие, которые следуют непосредственно друг за другом.

E + F { стиль }

Например такая разметка:

<h1>Заголовок</h1>
<p>Первый абзац</p>
<p>Текст</p>
<p>Текст</p>

Если задать:

h1 + p { color: red; }

то первый абзац получится красным цветом.


Селекторы атрибутов позволяют задавать стили для тех тэгов у которых указан определенный атрибут. Вы уже знаете например атрибут class, style, href, src и т.п.

E[атрибут] { стиль }
Например нам нужно подсветить красным все H1, у которых указан атрибут class:
h1[class] { color: red; }

В разметке:

<h1>Заголовок1</h1>
<h1 class="my">Заголовок2</h1>

красным окажется заголовок 2, поскольку у первого нет атрибута class.

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


Применяется к тем элементам, у которых задан атрибут и его точное значение.

E[атрибут="значение"] { стиль }

a[target="_blank"] { color: red; }

<a href="#" target="_blank">ссылка</a>

Применяется к элементам у которых атрибут начинается с указанного текста.

E[атрибут^="значение"] { стиль }

a[href^="http://"] { color: red; }

<a href="http://google.com/">ссылка</a>

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

E[атрибут$="значение"] { стиль }

a[href$=".com"] { color: red; }

<a href="http://google.com">ссылка</a>

Применяется если указанный текст встречается в любом месте атрибута.

E[атрибут*="значение"] { стиль }

a[href*="google"] { color: red; }

<a href="http://google.com/">ссылка</a>

Применяется для поиска в атрибуте фразы отделенную пробелом, как например в мультиклассах (там где указываются два и более класса).

E[атрибут~="значение"] { стиль }

a[class~="my"] { color: red; }

<a class="bold my big" href="#">ссылка</a>

Применяется для поиска в атрибуте фразы отделенную/заканчивающуюся дефисом.

E[атрибут|="значение"] { стиль }

a[class|="my"] { color: red; }

<a class="my-red" href="#">ссылка</a>

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

Часто бывают ситуации, когда свойства повторяются у разных селекторов.

a       { color: red; }
div.red { color: red; }
h1.my   { color: red; }

Такую запись можно сократить, перечислив селекторы через запятую:

a,
div.red, 
h1.my { 
	color: red; 
}

Это уменьшает css-код и часто применяется на практике, особенно когда нужно сгруппировать элементы с одинаковым оформлением.

Специфичность селектора

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

В расчёте используются 4 коэффициента: a, b, c, d. Результат записывается в виде a-b-c-d и чем больше число (мысленно уберите дефисы), тем больше специфичность (его приоритет).

За каждый тэг и превдоэлемент увеличивается коэффициент d. При этом без разницы какие между ними существуют отношения:

li             {}  0-0-0-1
li::first-line {}  0-0-0-2
ul li          {}  0-0-0-2
ul > li        {}  0-0-0-2
ul li a        {}  0-0-0-3
ul > li + a    {}  0-0-0-3

За каждый указанный атрибут или псевдокласс увеличивается коэффициент c. Атрибутом может быть например класс.

.red        {}  0-0-1-0
a.red       {}  0-0-1-1
a:hover     {}  0-0-1-1
a.red.bold  {}  0-0-2-1
Псевдоэлементы и псевдоклассы будем рассматривать в следующем уроке.

За указание id увеличивается коэффициент b.

#mylink     {} 0-1-0-0

За указание style увеличивается коэффициент a.

a { color: blue; }       0-0-0-1
div a { color: red; }    0-0-0-2
#mylink {color: gold;}   0-1-0-0

<div>
	<a href="#" id="mylink" style="color: green;">ссылка</a>  1-0-0-0
</div>
За универсальный селектор * никакие коэффициенты не увеличиваются.

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

a                 { color: blue; }    0-0-0-1
a.red             { color: red; }     0-0-1-1
div a             { color: orange; }  0-0-0-2
div a.red         { color: gold; }    0-0-1-2
div.myblock a.red { color: navy; }    0-0-2-2

<div class="myblock">
	<a href="#" class="red">ссылка</a>
</div>

В данном примере наибольший вес имеет правило div.myblock a.red и значит ссылка будет color: navy;

Бывают ситуации, когда вес оказывается одинаковым. В этом случае приоритет имеет последнее объявленное правило.

a                  { color: blue; }    0-0-0-1
a.red              { color: red; }     0-0-1-1
div a              { color: orange; }  0-0-0-2
div a.red          { color: gold; }    0-0-1-2
div.myblock a.red  { color: navy; }    0-0-2-2
div.myblock1 a.red { color: yellow; }  0-0-2-2

<div class="myblock myblock1">
	<a href="#" class="red">ссылка</a>
</div>

Ссылка будет желтой (yellow), поскольку правило просто оказалось ниже по css-коду (при таком же по весу селекторе).

Если нужно как-то явно «перебить» любую специфичность, используется правило !important, которое задаётся у каждого свойства. Оно как-бы добавляет еще один разряд перед всеми числами.

a                  { color: blue !important; }    1-0-0-0-1
a.red              { color: red; }     	0-0-1-1
div a              { color: orange; }  	0-0-0-2
div a.red          { color: gold; }    	0-0-1-2
div.myblock a.red  { color: navy; }    	0-0-2-2
div.myblock1 a.red { color: yellow; }   0-0-2-2

<div class="myblock myblock1">
	<a href="#" class="red">ссылка</a>
</div>

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

Ручное вычисление специфичности интересно само по себе, но несколько лишено смысла при использовании инструментов отладки FireFox. Нажмите на любом интересующем вас элементе страницы второй кнопкой мыши и выберите пункт «Исследовать элемент». Откроется панель вебмастера, где справа (в зависимости от настроек панели) будут перечисленны все css-свойства элемента.

В данном примере хорошо видно, что работает правило a { color: blue !important; }, а остальные перечеркнуты.

Задания

Задания доступны только после авторизации.