Структурные псевдо-классы и псевдо-элементы
Данный урок является последним в серии, посвященной селекторам CSS. В первом уроке были рассмотрены селекторы атрибутов, во втором — комбинаторы и некоторые псевдо-классы. Завершим обзор селекторов разбором структурных псевдо-классов и псевдо-элементов.
Примечание: в скобках указан вариант стандарта CSS, в котором был введен селектор.
Структурные псевдо-классы
Структурные псевдо-классы были введены как способ указать элементы HTML на основе информации в дереве документа, которую сложно просто представить с помощью простых селекторов и комбинаторов. Большинство из них введено в CSS3.
Без них приходится использовать класс или идентификатор для указания элемента.
E:root (3) — соответствует элементу E, который является корневым для документа. В HTML это всегда элемент html.
1 :root {background: blue;}
2 html {background: blue;}
Обе строчки примера выполняют одинаковые функции. Вероятно, пока данный селектор является бесполезным.
E:nth-child(n) (3) — соответствует элементу E, который является n-ым потомком своего родителя.
Предположим, у нас есть таблица с большим количеством строк.
1 tr:nth-child(4) {background: #ccc;}
Код примера будет задавать светло-серый цвет для каждой 4-й строки.
Распространенное использование данного псевдо-класса — определение цвета для n-ой строки в таблице.
1 tr:nth-child(2n+1) {background: #ccc;}
2 tr:nth-child(2n) {background: #eee;}
2n+1 представляет нечетные строки, а 2n — четные. Можно использовать специальные значения для указания четных и нечетных строк.
1 tr:nth-child(odd) {background: #ccc;}
2 tr:nth-child(even) {background: #eee;}
Можно использовать любой номер:
1 tr:nth-child(10n+1) {background: #ccc;}
Код будет определять цвет фона для 11-й, 21-й, 31-й и так далее строк.
E:nth-last-child(n) (3) — соответствует элементу E, который является n-ым потомком своего родителя, считая от последнего потомка.
Псевдо-класс nth-last-child работает аналогично nth-child, за исключением того, что подсчет ведется от последнего элемента в списке.
Снова предположим, что у нас есть таблица с большим количеством строк.
1 tr:nth-last-child(1) {background: #ccc;}
Код будет устанавливать цвет фона для последней строки.
1 tr:nth-last-child(4) {background: #ccc;}
А здесь 4-я строка с конца таблицы будет иметь соответствующий цвет фона.
Также можно использовать значения для указания четных и нечетных строк:
1 tr:nth-last-child(2n+1) {background: #ccc;}
2 tr:nth-last-child(2n) {background: #eee;}
3
4 tr:nth-last-child(odd) {background: #ccc;}
5 tr:nth-last-child(even) {background: #eee;}
Типовое использование псевдо-класса nth-last-child — установка особенных стилей для последних пунктов списка (например, для строк с итогами).
:nth-of-type и:nth-last-of-type
Остальные структурные псевдо-классы работают аналогично двум вышеописанным псевдо-классам. Так что если вам понятно их действие, то и все остальное будет представлять собой четкую картину, останется только разобраться в отличиях.
E:nth-of-type(n) (3) — соответствует элементу E, который является n-ым в списке смежных элементов данного типа.
E:nth-last-of-type(n) (3) — соответствует элементу E, который является n-ым с конца в списке смежных элементов данного типа.
nth-of-type() и nth-last-of-type() работают аналогично nth-child() и nth-last-child(). Разница заключается в том, что для указания элементов используется тип, а не родственные отношения.
Следует использовать псевдо-классы -of-type, когда родительский элемент имеет отличный от потомков тип.
HTML
01 <div>
02 <p></p>
03 < img src="/" alt="" / >
04 <p></p>
05 <ul>
06 <li></li>
07 <li></li>
08 </ul>
09 <p></p>
10 </div>
CSS
1 p:nth-of-type(2) {font-size: 1.2em;}
2 p:nth-last-of-type(1) {font-size: 1.2em;}
Наверняка, вы догадались, какой параграф будет иметь какой цвет. В данном случае использовались псевдо-классы -of-type, так как элементы внутри div имеют разные типы.
:first-child и :last-child
Данные псевдо-классы представляют собой короткую запись для nth-child(1) и nth-last-child(1). Требуется, чтобы потомки были одного типа.
E:first-child (2) — соответствует элементу E, который является первым потомком своего родителя.
E:last-child (3) — соответствует элементу E, который является последним потомком своего родителя.
Типовое использование данного псевдо-класса — определение стилей для первого и последнего элемента в навигационной панели, где крайние элементы могут немного отличаться от средних. Например, задание рамки для пунктов меню.
:first-of-type и :last-of-type
Данные два псевдо-класса представляют собой функциональный эквивалент nth-of-type(1) и nth-last-of-type(1) соответственно. Они работают так же, как и first-child и last-child, за исключением того, что указывается элемент определенного типа.
E:first-of-type (3) — соответствует элементу E, который является первым в списке смежных элементов данного типа.
E:last-of-type (3) — соответствует элементу E, который является последним в списке смежных элементов данного типа.
Типовое использование данного псевдо-класса — определение специальных стилей для первого и последнего параграфа в статье.
only-child и only-of-type
Следующие два псевдо-класса служат для выделения единственных элементов.
E:only-child (3) — соответствует элементу E, который является единственным потомком своего родителя.
E:only-of-type (3) — соответствует элементу E, который является единственным с данным типом среди смежных элементов.
С помощью псевдо-класса only-child выделяется единственный элемент внутри родителя. А псевдо-класс only-of-type поможет выбрать уникальный элемент с определенным типом среди нескольких потомков.
:empty
E:empty (3) — соответствует элементу E, который не имеет потомков (включая текстовое содержание)
Псевдо-класс :empty является способом указать пустой тег. Например, ему не будет соответствовать следующий элемент:
1 <p>Какой-нибудь текст</p>
А вот такой элемент соответствует данному псевдо-классу:
1 <p></p>
В идеале вы не должны оставлять пустых тегов в разметке HTML. Поэтому польза данного псевдо-класса весьма сомнительна. Может быть, он будет представлять способ определения и удаления пустых тегов, которые случайным образом оставлены в коде.
Псевдо-элементы
Существуют некоторые моменты реальной практики, когда нужно задать определенные стили различным частям разметки, но нет способа выделения таких частей на основе информации из дерева документа. Обычно, в таких случаях добавляются элементы (например, span) и для них задаются классы.
У нас есть 4 псевдо-элемента, которые могут помочь определению стилей для особых случаев без создания лишних элементов в структуре DOM.
::first-line
E::first-line (1) — соответствует первой сформированной строке элемента E.
1 p:first-line {text-transform: uppercase;}
Пример будет изменять первую строку всех параграфов (текст будет выводиться заглавными буквами). Конечно же, первая строка текста может динамически изменяться, если используется резиновый шаблон или варьируется ширина элемента.
::first-letter
E::first-letter (1) — соответствует первому символу элемента E.
Как и first-line, first-letter выбирает только первый символ. Очевидное использование — выделение первой буквы.
HTML
1 <p class="intro">Первая строка параграфа</p>
CSS
1 p.intro::first-letter {
2 font-size:4em;
3 font-weight:bold;
4 color: #f00;
5 float:left;
6 }
::before и ::after
E::before (2) — соответствует сгенерированному содержанию до элемента E.
E::after (2) — соответствует сгенерированному содержанию после элемента E.
Псевдо-элементы ::before и ::after являются способом добавить содержание до и после элемента. Обычное использование — добавление изображения кавычек до и после цитаты, или вставка специальных символов перед пунктами списка.
HTML
1 <blockquote>Текст цитаты</blockquote>
CSS
1 blockquote::before {content: "‘"}
2 blockquote::after {content: "’"}
Код примера добавляет кавычки до цитаты и после нее.
The above adds a single left quotation mark before the blockquote and a single right quotation mark after it.
В некоторых случаях не нужно добавлять никакого содержания, а требуется только изменить стили с помощью ::before и ::after. Нужно обязательно включить свойство content:, но оставить его пустым.
1 blockquote::before {content: "";}