Псевдоклассы, псевдоэлементы

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

Необходимые условия: Базовая компьютерная грамотность, установка базового ПО, базовые знания о работе с файлами, основы HTML (изучите Введение в HTML) и понимание работы CSS (изучите Введение в CSS.)
Цель: Узнать о селекторах псевдокласса и псевдоэлемента.

Что такое псевдокласс?

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

Псевдоклассы — это ключевые слова, которые начинаются с двоеточия:

:pseudo-class-name

Простой пример псевдокласса

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

Однако поддержка может оказаться утомительной — что если новый абзац будет добавлен в верхнюю часть документа? Тогда нам нужно будет передвинуть класс к новому абзацу. Вместо добавления класса мы могли бы использовать селектор псевдокласса :first-child — он всегда будет нацелен на первый дочерний элемент в статье, и нам больше не нужно будет редактировать HTML (к тому же это не всегда возможно, например, в случае если он генерируется CMS.)

Все псевдоклассы ведут себя подобным образом. Они нацелены на какой-то фрагмент вашего документа, находящийся в определённом состоянии, и ведут себя так, как если бы вы добавили класс в свой HTML. Рассмотрим некоторые другие примеры в MDN:

Примечание: Правильно писать псевдоклассы и элементы без какого бы то ни было предшествующего им селектора элемента. В примере выше вы могли бы написать :first-child и правило было бы применено к любому элементу, оказавшемуся первым дочерним для <article>, не только к первому дочернему абзацу — :first-child равнозначно *:first-child. Однако обычно вы хотите большего контроля, поэтому вам нужен более специфичный селектор.

Псевдоклассы пользовательского действия

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

  • :hover — упоминался выше; он применяется только в том случае, если пользователь наводит указатель мыши на элемент, обычно на ссылку.
  • :focus — применяется только в том случае, если пользователь фокусируется на элементе, используя управление с клавиатуры.

Что такое псевдоэлемент?

Псевдоэлементы ведут себя сходным образом, однако они действуют так, как если бы вы добавили в разметку целый новый HTML-элемент, а не применили класс к существующим элементам. Псевдоэлементы начинаются с двойного двоеточия ::.

::pseudo-element-name

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

Например, если вы хотите выбрать первую строку абзаца, вы могли бы обернуть её в <span> и использовать селектор элемента; однако это может не сработать, если количество слов, которые вы обернули, будет больше или меньше ширины родительского элемента. Поскольку мы, как правило, не знаем, сколько слов поместится в строке — т.к. их количество меняется, если меняется ширина экрана или размер шрифта — то надёжного решения при помощи HTML нет.

Селектор псевдоэлемента ::first-line сделает это наверняка — если количество слов увеличивается или уменьшается, он всё равно будет выбирать только первую строку.

Он действует так, как если бы <span> волшебным образом был обёрнут вокруг этой первой отформатированной строки и обновлялся бы каждый раз при изменении длины строки.

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

Объединение псевдоклассов и псевдоэлементов

Если вы хотите сделать шрифт первой строки первого абзаца жирным, вы можете связать вместе селекторы :first-child и ::first-line. Попробуйте отредактировать предыдущий живой пример, чтобы использовалась следующая CSS. Мы говорим, что хотим выбрать первую строку первого элемента <p>, который находится внутри элемента <article>.

css
article p:first-child::first-line {
  font-size: 120%;
  font-weight: bold;
}

Генерация контента с помощью ::before и ::after

Существует пара специальных псевдоэлементов, которые используются вместе со свойством content для вставки содержимого в документ с помощью CSS.

Вы можете использовать их для вставки строки текста, как в приведённом ниже живом примере. Попробуйте изменить текстовое значение свойства content и вы увидите, как изменится результат. Можете также изменить псевдоэлемент ::before на ::after и увидите, что текст вставлен в конце элемента, а не в начале.

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

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

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

В следующем примере мы добавили пустую строку, используя псевдоэлемент ::before. Мы установили display: block, чтобы стилизовать его по ширине и высоте. Затем мы используем CSS, чтобы стилизовать его так же, как и любой другой элемент. Вы можете поиграть с CSS и изменить его внешний вид и поведение.

Использование псевдоэлементов ::before и ::after вместе со свойством content в CSS называется "генерируемым контентом" в CSS, и вы часто будете видеть, как этот метод используется для различных задач. Отличным примером является сайт CSS Arrow Please, который помогает вам генерировать стрелку с помощью CSS. Посмотрите на CSS, когда вы создадите свою стрелку, и вы увидите использование псевдо-элементов ::before и ::after. Всякий раз, когда вы будете видеть эти селекторы, смотрите на свойство content, чтобы увидеть, что добавляется в документ..

Справочный раздел

Существует большое количество псевдоклассов и псевдоэлементов, и полезно иметь список, к которому можно обращаться. Ниже приведены таблицы, в которых они перечислены, со ссылками на их справочные страницы в MDN. Используйте эти таблицы как справочник, чтобы видеть массив доступных вам средств для нацеливания на элементы.

Псевдоклассы

Селектор Описание
:active Подходит, когда пользователь активирует (например, щёлкает мышью) элемент.
:any-link Соответствует как состоянию :link, так и состоянию:visited ссылки.
:blank Соответствует элементу <input>, для которого значение ввода является пустым.
:checked Соответствует переключателю или флажку в выбранном состоянии.
:current Соответствует элементу или предку элемента, который в данный момент отображается.
:default Соответствует одному или нескольким элементам пользовательского интерфейса, которые являются элементами по умолчанию (обрабатывают нажатие клавиши enter) в наборе сходных элементов.
:dir Выбирает элемент на основе его направленности (значение атрибута HTML dir или свойства CSS direction ).
:disabled Соответствует элементам пользовательского интерфейса, которые находятся в отключённом состоянии.
:empty Соответствует элементу, у которого нет дочерних элементов, кроме необязательного пробела.
:enabled Соответствует элементам пользовательского интерфейса, которые находятся во включённом состоянии.
:first В постраничном носителе соответствует первой странице.
:first-child Соответствует элементу, который является первым среди других дочерних элементов одного предка.
:first-of-type Соответствует элементу, который является первым определённого типа среди других дочерних элементов одного предка.
:focus Соответствует элементу, имеющему фокус.
:focus-visible Соответствует элементу, имеющему фокус, при этом фокус должен быть виден пользователю.
:focus-within Соответствует элементу с фокусом, а также элементу с потомком, который имеет фокус.
:future Соответствует элементам после текущего элемента.
:hover Соответствует элементу, на который наведён курсор мыши.
:indeterminate Соответствует элементам пользовательского интерфейса, значение которых находится в неопределённом состоянии, обычно checkboxes.
:in-range Соответствует элементу с диапазоном, когда его значение находится в пределах диапазона.
:invalid Соответствует элементу, например <input>, в недопустимом состоянии.
:lang Соответствует элементу, основанному на языке (значение атрибута HTML lang).
:last-child Соответствует элементу, который является последним среди других дочерних элементов одного предка.
:last-of-type Соответствует элементу, который является последним определённого типа среди других дочерних элементов одного предка.
:left В постраничном носителе соответствует левосторонним страницам.
:link Соответствует непосещавшимся ссылкам.
:local-link Соответствует ссылкам, указывающим на страницы, которые расположены на том же сайте, что и текущий документ.
:is() Соответствует любому селектору из полученного списка селекторов.
:not Соответствует объектам, не входящим в список селекторов, переданный в качестве значения этому селектору.
:nth-child Соответствует элементам из списка дочерних элементов одного предка, которые подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечётные числа.)
:nth-of-type Соответствует элементам из списка дочерних элементов одного предка, имеющим определённый тип (например, элементы <p>) — дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать элементам 1, 3, 5, 7 и т. д. Все нечётные числа.)
:nth-last-child Соответствует элементам из списка дочерних элементов одного предка, считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечётные, считая с конца.)
:nth-last-of-type Соответствует элементам из списка дочерних элементов одного предка, имеющим определённый тип (например, элементы <p>), считая в обратном порядке от конца. Дочерние элементы подобраны по формуле вида an+b (например, 2n + 1 будет соответствовать последнему элементу этого типа в последовательности, затем на два элемента до него, затем ещё на два элемента назад и т. д. Все нечётные, считая с конца.)
:only-child Соответствует элементу, являющемуся единственным дочерним для своего предка.
:only-of-type Соответствует элементу, который отличается по типу от всех других дочерних элементов общего предка.
:optional Соответствует необязательным элементам формы.
:out-of-range Соответствует элементу с диапазоном, когда его значение находится вне диапазона.
:past Соответствует элементам перед текущим элементом.
:placeholder-shown Соответствует элементу input, который показывает текст-заполнитель.
:playing Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями "воспроизведён" или "приостановлен", когда этот элемент "воспроизводится".
:paused Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями "воспроизведён" или "приостановлен", когда этот элемент "приостановлен".
:read-only Соответствует элементу, который не может быть изменён пользователем.
:read-write Соответствует элементу, который может быть изменён пользователем.
:required Соответствует обязательным элементам формы.
:right В постраничном носителе соответствует правосторонним страницам.
:root Соответствует элементу, который является корнем документа.
:scope Соответствует любому элементу, который является элементом области видимости.
:valid Соответствует элементу, такому как <input>, в допустимом состоянии.
:target Соответствует элементу, если он является целью текущего URL (т. е. если у него есть ID, соответствующий текущему URL fragment).
:visited Соответствует посещённым ссылкам.

Псевдоэлементы

Селектор Описание
::after Соответствует элементу, который допускает стилизацию и появляется после текущего содержимого порождающего элемента.
::before Соответствует элементу, который допускает стилизацию и появляется перед текущим содержимым порождающего элемента.
::first-letter Соответствует первой букве элемента.
::first-line Соответствует первой строке содержимого порождающего элемента.
::grammar-error Соответствует части документа, содержащей грамматическую ошибку, отмеченную браузером.
::marker Соответствует полю маркера пункта списка, которое обычно содержит жирную точку или число.
::selection Соответствует части документа, которая была выбрана.
::spelling-error Соответствует части документа, содержащей орфографическую ошибку, отмеченную браузером.