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

css-pseudo-classesПсевдоклассы описывают характеристики элементов, такие как динамическое состояние — нажатая ссылка, язык кодировки — абзац на французском языке и т.д. Они не отображаются в исходном документе и не принадлежат дереву документа DOM (дереву документа принадлежат только сами html-элементы).

Разметка html-страниц создаётся с помощью html-элементов. Для каждого html-элемента существуют css-стили по-умолчанию, так называемые стили браузера, например, полужирное начертание и разный размер шрифта заголовков h1-h6, подчёркивание и фиолетовый цвет текста ссылки. Эти стили по-умолчанию можно изменять, а также задавать дополнительные, пользовательские, с помощью таблиц стилей.

Без использования псевдоклассов изменить внешний вид по-умолчанию и задать индивидуальный для каждого элемента можно только используя селектор — имя тега, класс или идентификатор элемента. Но как быть в случае, когда нужно выделить фоном каждую чётную строку таблицы? Прописывать классы вручную для каждой строки таблицы займёт много времени и значительно увеличит разметку. В такой ситуации на помощь приходит псевдокласс :nth-child(even), и с помощью селектора tr:nth-child(even) автоматически устанавливается фон для каждой чётной строки таблицы.

pseudo-class-tr
Рис. 1. Таблица-зебра с помощью класса и псевдокласса

В процессе взаимодействия пользователя со страницей html-элементы приобретают динамические характеристики. Например, когда вы переходите по ссылке, html-элемент <a>текст ссылки</a> приобретает следующие свойства (характеристики): когда вы наводите на ссылку, она получает a:hover, когда вы уже перешли по ссылке — a:visited. Доступ к таким динамическим характеристикам можно получить только с помощью псевдоклассов.

Таким образом, с помощью псевдоклассов можно получить доступ к информации, характеризующей элемент, которая не может быть получена с помощью простых селекторов — p {css-стили} или их комбинации — h1 + p {css-стили}.

Псевдоклассы делятся на статические, например, :last-of-type, и динамические, например, :hover, т.е. появляющиеся у элемента в процессе взаимодействия пользователя с веб-страницей. Имена псевдоклассов чувствительны к регистру. Некоторые псевдоклассы взаимоисключающие, в то время как другие могут одновременно применяться к одному элементу.

Виды псевдоклассов

1. Динамические псевдоклассы

Выбирают ссылки на странице, которые имеют атрибут href и находятся в определенном состоянии, а также некоторые другие элементы:

:link — не посещенная ссылка;

:visited — посещенная ссылка;

:focus — ссылки, а также элементы форм, над которыми находится курсор мыши или на которые перешли с помощью кнопки TAB;

:hover — ссылки, а также другие элементы, стили применяются при наведении пользователем на элемент;

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

2. Псевдоклассы пользовательского интерфейса

Относятся к элементам форм.

:disabled — используется для отбора и стилизации заблокированных для выбора и изменения элементов форм;

:enabled — отбирает не заблокированные для выбора и изменения элементы форм;

:checked — применяется для выбора и стилизации элементов <input type="radio">, <input type="checkbox">, а также элементов <option></option>, находящихся внутри элемента <select></select>;

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

3. Структурные псевдоклассы

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

:root — элемент, являющийся корневым в документе;

:nth-child() — элементы на основе их индекса (в порядке очереди) внутри их родительского контейнера. Варианты:
li:nth-child(even) — каждый элемент списка с индексом 2, 4, 6, 8, и т.д.
li:nth-child(odd) — каждый элемент списка с индексом 1, 3, 5, 7, и т.д.
li:nth-child(3) — только элемент с индексом 3.
li:nth-child(an+b) — например, li:nth-child(3n+1) выберет первый (3*0 +1 = 1), четвёртый (3*1 +1 = 4), седьмой (3*2 +1 = 7) элементы и т.д., причём значение b может быть равно нулю;

:nth-last-child() — дочерние элементы на основе их индекса внутри контейнера, при этом отсчёт идёт в обратном порядке, т.е. начиная с последнего элемента. Значениями аргумента могут быть положительные, отрицательные значения, а также ключевые слова even odd;

:nth-of-type() — элементы одного типа на основе их индекса внутри контейнера, например, img:nth-of-type(2n) {float: left;} установит обтекание по левому краю каждой четной картинке, при условии, что они каждая из них не обёрнута другим блоком;

:nth-last-of-type() — элементы одного типа на основе их индекса внутри контейнера, начиная с последнего элемента к первому;

:first-child — элемент, который является первым дочерним элементом некоторого другого элемента;

:last-child — последний дочерний элемент элемента-контейнера;

:first-of-type — первый элемент данного типа среди дочерних элементов родительского элемента-контейнера;

:last-of-type — последний элемент данного типа среди дочерних элементов родительского элемента-контейнера;

:only-child — дочерний элемент, который является единственным дочерним элементов. Работает аналогично с :first-child:last-child или :nth-child(1):nth-last-child(1), но с меньшей специфичностью;

:only-of-type — элемент, который является единственным элементом данного типа в родительском элементе;

:empty — элемент, который не содержит ни одного дочернего элемента.

4. Целевой псевдокласс :target

Некоторые ссылки указывают на местоположение внутри ресурса. Этот тип ссылок заканчивается символом «решетка» #, за которым следует идентификатор якоря (так называемый идентификатор фрагмента), например https://html5book.ru/css3-flexbox/#align-content. Элемент с идентификатором фрагмента называется целевым элементом. С помощью данного псевдокласса можно стилизовать элемент, к которому перешли по ссылке на странице (навигация по странице), а также элементы, которые расположены в одном блоке и при нажатии на кнопку/ссылку сменяются/перемещаются (например, css-слайдер).

В данном примере каждой картинке задан id, а каждой ссылке — соответствующий идентификатор якоря. При нажатии на ссылку каждая картинка увеличивается до стопроцентного размера.

<div id="slideshow">
<img id="one" src="flower-1.jpg">
<img id="two" src="flower-2.jpg">
<nav>
  <a href="#one" class="current"></a>
  <a href="#two"></a>
</nav>
</div>
#slideshow img {transform: scale(0);}
#slideshow img:target {transform: scale(1);}

5. Языковой псевдокласс :lang()

Данный псевдокласс используется когда в документе содержатся абзацы текста на разных языках. Чтобы браузер различал их, элементу с текстом добавляется атрибут lang с кодом языка, например, lang="fr". В результате чего этот элемент может быть стилизован при помощи селектора p:lang(fr) {css-стили}.

6. Псевдокласс отрицания :not()

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

селекторы элемента, например, :not(strong)

селекторы класса и идентификатора, например, p:not(.text)

селекторы псевдокласса, например, ul:not(:first-child)

селекторы атрибута, например, input:not([type="checkbox"])

7. Комбинация псевдоклассов

При стилизации элементов возможна комбинация псевдоклассов, например:

tr:nth-last-child(even):hover — добавит стили при наведении каждой чётной строке таблицы (отсчёт в обратном порядке);

h2:not(:first-of-type):not(:last-of-type) — добавит стили для всех элементов данного типа, кроме первого и последнего элемента данного типа.

  • Создание Сайтов

    Такое наверное можно понять, а потом и самому применять, только после подробного мастер-класса. Лично для меня это все довольно туманно, что, куда, и как, и зачем.

    • Да, вы правы, слово «псевдоклассы» пугает одним названием. Я добавила немного объяснений, посмотрите, возможно вы найдёте знакомые слова, которые помогут понять назначение псевдоклассов.

      • Создание Сайтов

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

        • Я вас поняла, добавлю примеры с картинками.
          Как ни прискорбно признавать, но главная проблема тех, кто пишет про веб-технологии — они всё понимают и некоторые вещи подразумевают по умолчанию((
          Я как-то читала комментарий на мой сайт, что примеры в уроках разобраны не полностью. Но с этим позволю не согласиться, потому что если человек читает «как это сделано», но не изучает основы, в результате он ничего не поймёт и ничему не научится.
          Понять, как работают веб-технологии, можно только в результате штудирования основ и проверки свойств на примерах. И не страшно, что с первого раза вы вряд ли что-то поймёте. Читайте снова и снова, экспериментируйте — и у вас всё получится.

          • Создание Сайтов

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

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

    • Freeman4D

      • Если вам нужно выделить, пропустив некоторое количество с начала и с конца, не проще ли использовать :nth-child(n+3):nth-last-child(n+8)? Если браузеры отображают с багами ваш вариант, то скорее всего он не рабочий (ещё раз повторюсь, что не видела такой комбинации в официальной спецификации). Проверьте работу этого примера http://codepen.io/html5book/pen/VbYWvo.