Перейти к содержанию

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

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

CSS подкаст

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

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

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

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

Интерактивные состояния

Следующие псевдоклассы применяются при взаимодействии пользователя с вашей страницей.

:hover

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

:active

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

:focus, :focus-within и :focus-visible

Если элемент может получать фокус — например, <button> — вы можете реагировать на это состояние с помощью псевдокласса :focus.

Вы также можете реагировать на получение фокуса дочерним элементом вашего элемента с помощью функции :focus-within.

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

1
2
3
button:focus {
    outline: none;
}

Этот CSS удаляет кольцо фокуса браузера по умолчанию, когда элемент получает фокус, что создает проблему доступности для пользователей, перемещающихся по веб-странице с помощью клавиатуры. Если стиль фокуса отсутствует, то при использовании клавиши табуляции они не смогут отслеживать, где в данный момент находится фокус. С помощью :focus-visible можно представить стиль фокуса, когда элемент получает фокус с клавиатуры, и одновременно использовать правило outline: none, чтобы предотвратить его появление при взаимодействии с указателем.

1
2
3
4
5
6
7
button:focus {
    outline: none;
}

button:focus-visible {
    outline: 1px solid black;
}

:target

Псевдокласс :target выбирает элемент, у которого id совпадает с фрагментом URL. Допустим, у вас есть следующий HTML:

1
<article id="content"></article>

К этому элементу можно прикрепить стили, если в url содержится #content.

1
2
3
#content:target {
    background: yellow;
}

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

Состояния

Псевдокласс :link может быть применен к любому элементу <a>, имеющему значение href, который еще не был посещен.

:visited

С помощью псевдокласса :visited можно придать стиль ссылке, по которой пользователь уже перешел. Это состояние противоположно состоянию :link, однако в целях безопасности можно использовать меньше CSS-свойств. Вы можете стилизовать только color, background-color, border-color, outline-color и цвет SVG fill и stroke.

Порядок имеет значение

Если вы определяете стиль :visited, то он может быть отменен псевдоклассом ссылки, имеющим, по крайней мере, такую же специфику. В связи с этим рекомендуется использовать правило LVHA для стилизации ссылок с псевдоклассами в определенном порядке: :link, :visited, :hover, :active.

1
2
3
4
5
6
7
8
a:link {
}
a:visited {
}
a:hover {
}
a:active {
}

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

Состояния формы

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

:disabled и :enabled

Если элемент формы, например <button>, отключен браузером, вы можете использовать псевдокласс :disabled для хука этого состояния. Для противоположного состояния доступен псевдокласс :enabled, однако элементы формы по умолчанию также :enabled, поэтому вы можете не найти возможности воспользоваться этим псевдоклассом.

:checked и :indeterminate

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

Состояние :checked является бинарным (true или false), но у флажков есть промежуточное состояние, когда они не отмечены и не сняты. Это состояние называется :indeterminate.

Примером такого состояния может служить элемент управления "select all", который устанавливает флажки для всех флажков в группе. Если пользователь затем снимет флажок с одного из этих флажков, то корневой флажок больше не будет представлять "всех", поэтому его следует перевести в неопределенное состояние.

Элемент <progress> также имеет неопределенное состояние, которое может быть стилизовано. Обычно его используют для придания ему полосатого вида, чтобы показать, что неизвестно, сколько еще нужно сделать.

:placeholder-shown

Если поле формы имеет атрибут placeholder и без значения, то псевдокласс :placeholder-shown может быть использован для прикрепления стилей к этому состоянию. Как только в поле появится содержимое, независимо от того, есть ли в нем placeholder или нет, это состояние больше не будет применяться.

Состояния валидации

Вы можете реагировать на проверку HTML-формы с помощью таких псевдоклассов, как :valid, :invalid и :in-range. Псевдоклассы :valid и :invalid полезны в таких контекстах, как поле электронной почты, которое имеет pattern, которому необходимо соответствовать, чтобы оно было действительным. Это состояние допустимого значения может быть показано пользователю, помогая ему понять, что он может спокойно переходить к следующему полю.

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

В HTML-формах можно определить, что поле является обязательным, с помощью атрибута required. Для обязательных полей будет доступен псевдокласс :required. Поля, которые не являются обязательными, могут быть выбраны с помощью псевдокласса :optional.

Не стоит полагаться только на цвет для обозначения изменений состояния — особенно на красный и зеленый, поскольку дальтоники и слабовидящие пользователи могут с трудом заметить изменение состояния или даже полностью его пропустить. Хорошей идеей является использование цвета для поддержки изменения состояния, а также изменения текста и пиктограмм для визуального обозначения изменений

Выбор элементов по их индексу, порядку и месту появления

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

:first-child и :last-child

Если необходимо найти первый или последний элемент, можно использовать :first-child и :last-child. Эти псевдоклассы возвращают либо первый, либо последний элемент в группе элементов-братьев.

:only-child

Также можно выделить элементы, не имеющие братьев и сестер, с помощью псевдокласса :only-child.

:first-of-type и :last-of-type

Вы можете выбрать :first-of-type и :last-of-type, которые, на первый взгляд, делают то же самое, что и :first-child и :last-child, но рассмотрим этот HTML:

1
2
3
4
5
<div class="my-parent">
    <p>A paragraph</p>
    <div>A div</div>
    <div>Another div</div>
</div>

И этот CSS:

1
2
3
.my-parent div:first-child {
    color: red;
}

Ни один из элементов не будет окрашен в красный цвет, поскольку первым дочерним элементом является абзац, а не div. В этом контексте полезен псевдокласс :first-of-type.

1
2
3
.my-parent div:first-of-type {
    color: red;
}

Несмотря на то, что первый <div> является вторым дочерним элементом, он все равно является первым по типу внутри элемента .my-parent, поэтому в соответствии с этим правилом он будет окрашен в красный цвет.

:nth-child и :nth-of-type

Вы также не ограничены первым и последним дочерними элементами и типами. Псевдоклассы :nth-child и :nth-of-type позволяют указать элемент, находящийся под определенным индексом. Индексация в селекторах CSS начинается с 1.

В эти псевдоклассы можно передавать не только индекс. Если требуется выбрать все четные элементы, можно использовать :nth-child(even).

Также можно создавать более сложные селекторы, которые находят элементы с регулярными интервалами, используя микросинтаксис An+B.

1
2
3
li:nth-child(3n + 3) {
    background: yellow;
}

Этот селектор выбирает каждый третий элемент, начиная с элемента 3. n в этом выражении — это индекс, который начинается с нуля, а 3 (3n) — это то, на сколько вы умножаете этот индекс.

Допустим, у вас есть 7 элементов <li>. Первым выбирается элемент 3, поскольку 3n+3 переводится как (3 * 0) + 3. На следующей итерации будет выбран элемент 6, поскольку n теперь увеличилось до 1, поэтому (3 * 1) + 3). Это выражение работает как для :nth-child, так и для :nth-of-type.

Вы можете поиграть с подобным селектором на этом nth-child тестере или на этом quantity selector tool.

:only-of-type

Наконец, с помощью :only-of-type можно найти единственный элемент определенного типа в группе братьев и сестер. Это удобно, если необходимо выбрать списки, содержащие только один элемент, или найти единственный полужирный элемент в абзаце.

Поиск пустых элементов

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

:empty

Если элемент не имеет дочерних элементов, то к ним применяется псевдокласс :empty. Однако дочерними элементами могут быть не только HTML-элементы или текстовые узлы: они могут быть и пробелами, что может сбить с толку при отладке следующего HTML-файла, когда вы задаетесь вопросом, почему он не работает с :empty:

1
<div></div>

Причина заключается в том, что между открывающим и закрывающим <div> есть пробельные символы, поэтому empty не будет работать.

Псевдокласс :empty может быть полезен, если у вас мало контроля над HTML и вы хотите скрыть пустые элементы, например, в редакторе WYSIWYG-контента. Здесь редактор добавил пустой абзац.

1
2
3
4
5
6
7
<article class="post">
    <p>
        Donec ullamcorper nulla non metus auctor fringilla.
    </p>
    <p></p>
    <p>Curabitur blandit tempus porttitor.</p>
</article>

С помощью :empty это можно найти и скрыть.

1
2
3
.post :empty {
    display: none;
}

Нахождение и исключение нескольких элементов

Некоторые псевдоклассы помогают писать более компактный CSS.

:is()

Если вы хотите найти все дочерние элементы h2, li и img в элементе .post, вы можете написать список селекторов следующим образом:

1
2
3
4
5
.post h2,
.post li,
.post img {
    /* … */
}

С помощью псевдокласса :is() можно написать более компактную версию:

1
2
3
.post :is(h2, li, img) {
    /* … */
}

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

:not()

Также можно исключить элементы с помощью псевдокласса :not(). Например, с его помощью можно стилизовать все ссылки, не имеющие атрибута class.

1
2
3
a:not([class]) {
    color: blue;
}

Псевдокласс :not также может помочь улучшить доступность. Например, <img> должен иметь alt, даже если это пустое значение, поэтому можно написать CSS-правило, добавляющее толстый красный контур к недействительным изображениям:

1
2
3
img:not([alt]) {
    outline: 10px red;
}

Источник: Pseudo-classes

Комментарии