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

* Назад
* Обзор: Building blocks
* Далее

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

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

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

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

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

:pseudo-class-name
```

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

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

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

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

* `:last-child`
* `:only-child`
* `:invalid`

**Примечание:** Правильно писать псевдоклассы и элементы без какого бы то ни было предшествующего им селектора элемента. В примере выше вы могли бы написать `: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` (en-US) | Соответствует элементу или предку элемента, который в данный момент отображается. |
| `:default` | Соответствует одному или нескольким элементам пользовательского интерфейса, которые являются элементами по умолчанию (*обрабатывают нажатие клавиши enter*) в наборе сходных элементов. |
| `:dir` | Выбирает элемент на основе его направленности (значение атрибута HTML `dir` (en-US) или свойства CSS `direction` ). |
| `:disabled` | Соответствует элементам пользовательского интерфейса, которые находятся в отключённом состоянии. |
| `:empty` | Соответствует элементу, у которого нет дочерних элементов, кроме необязательного пробела. |
| `:enabled` | Соответствует элементам пользовательского интерфейса, которые находятся во включённом состоянии. |
| `:first` | В постраничном носителе соответствует первой странице. |
| `:first-child` | Соответствует элементу, который является первым среди других дочерних элементов одного предка. |
| `:first-of-type` | Соответствует элементу, который является первым определённого типа среди других дочерних элементов одного предка. |
| `:focus` | Соответствует элементу, имеющему фокус. |
| `:focus-visible` | Соответствует элементу, имеющему фокус, при этом фокус должен быть виден пользователю. |
| `:focus-within` | Соответствует элементу с фокусом, а также элементу с потомком, который имеет фокус. |
| `:future` (en-US) | Соответствует элементам после текущего элемента. |
| `:hover` | Соответствует элементу, на который наведён курсор мыши. |
| `:indeterminate` | Соответствует элементам пользовательского интерфейса, значение которых находится в неопределённом состоянии, обычно checkboxes (en-US). |
| `:in-range` | Соответствует элементу с диапазоном, когда его значение находится в пределах диапазона. |
| `:invalid` | Соответствует элементу, например `<input>`, в недопустимом состоянии. |
| `:lang` | Соответствует элементу, основанному на языке (значение атрибута HTML lang). |
| `:last-child` | Соответствует элементу, который является последним среди других дочерних элементов одного предка. |
| `:last-of-type` | Соответствует элементу, который является последним определённого типа среди других дочерних элементов одного предка. |
| `:left` | В постраничном носителе соответствует левосторонним страницам. |
| `:link` | Соответствует непосещавшимся ссылкам. |
| `:local-link` (en-US) | Соответствует ссылкам, указывающим на страницы, которые расположены на том же сайте, что и текущий документ. |
| `: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` (en-US) | Соответствует элементам перед текущим элементом. |
| `:placeholder-shown` | Соответствует элементу input, который показывает текст-заполнитель. |
| `:playing` (en-US) | Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями "воспроизведён" или "приостановлен", когда этот элемент "воспроизводится". |
| `:paused` (en-US) | Соответствует элементу, представляющему аудио, видео или подобный ресурс с возможными состояниями "воспроизведён" или "приостановлен", когда этот элемент "приостановлен". |
| `:read-only` | Соответствует элементу, который не может быть изменён пользователем. |
| `:read-write` | Соответствует элементу, который может быть изменён пользователем. |
| `:required` | Соответствует обязательным элементам формы. |
| `:right` | В постраничном носителе соответствует правосторонним страницам. |
| `:root` | Соответствует элементу, который является корнем документа. |
| `:scope` (en-US) | Соответствует любому элементу, который является элементом области видимости. |
| `:valid` | Соответствует элементу, такому как <input>, в допустимом состоянии. |
| `:target` | Соответствует элементу, если он является целью текущего URL (т. е. если у него есть ID, соответствующий текущему URL fragment). |
| `:visited` | Соответствует посещённым ссылкам. |

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

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

* Назад
* Обзор: Building blocks
* Далее