Ниже приводится выдержка из нашей книги CSS Master , написанной Тиффани Б. Браун. Копии продаются в магазинах по всему миру, или вы можете купить их в электронном виде здесь .
Как упоминалось ранее в этой главе, псевдоклассы помогают нам определять стили для документов на основе информации, которую невозможно извлечь из дерева документов или на которую нельзя ориентироваться с помощью простых селекторов. К ним относятся логические и лингвистические псевдоклассы, такие как :not()
и :lang()
. Он также включает инициируемые пользователем псевдоклассы, такие как :hover
и :focus
.
В этом разделе мы рассмотрим некоторые эзотерические и менее известные псевдоклассы с акцентом на то, что доступно в браузерах: индексированные и типизированные дочерние псевдоклассы и входные псевдоклассы. Индексируемые и типизированные дочерние индексированные псевдоклассы позволяют нам выбирать элементы по их положению в поддереве документа. Входные псевдоклассы целевые поля формы на основе их входных значений и состояний.
Выделение фрагментов страницы с помощью :target
Идентификатор фрагмента — это часть URL, которая следует за #
; например, #top
или #footnote1
. Вы, вероятно, использовали их для создания навигации внутри страницы: так называемой «ссылки перехода». С помощью псевдокласса :target
мы можем выделить часть документа, которая соответствует этому фрагменту, и мы можем сделать это без JavaScript.
Скажем, например, что у вас есть серия комментариев или тема на форуме:
<section id="comments"> <h2>Comments on this post</h2> <article class="comment" id="comment-1146937891">...</article> <article class="comment" id="comment-1146937892">...</article> <article class="comment" id="comment-1146937893">...</article> </section>
С некоторыми CSS-кодами и другими причудливыми элементами это немного похоже на то, что вы видите на рисунке ниже.
Каждый комментарий в вышеупомянутом коде имеет идентификатор фрагмента, что означает, что мы можем напрямую ссылаться на него. Например, <a href="#comment-1146937891">
. Затем все, что нам нужно сделать, это указать стиль для этого комментария, используя псевдокласс :target
:
.comment:target { background: #ffeb3b; border-color: #ffc107 }
Когда часть идентификатора фрагмента URL совпадает с частью комментария (например, http://example.com/post/#comment-1146937891
), этот комментарий будет иметь желтый фон, как показано ниже.
Вы можете использовать любую комбинацию CSS с :target
, что открывает некоторые забавные возможности, такие как закладки без JavaScript. Крейг Баклер подробно описывает эту технику в своем уроке «Как создать элемент управления вкладками только для CSS3 с помощью :target
Selector». Мы немного его обновим, чтобы использовать больше функций CSS3. Сначала давайте посмотрим на наш HTML:
<div class="tabbed-widget"> <div class="tab-wrap"> <a href="#tab1">Tab 1</a> <a href="#tab2">Tab 2</a> <a href="#tab3">Tab 3</a> </div> <ul class="tab-body"> <li id="tab1"> <p>This is tab 1.</p> </li> <li id="tab2"> <p>This is tab 2</p> </li> <li id="tab3"> <p>This is tab 3.</p> </li> </ul> </div>
Это довольно просто, состоит из вкладок и связанного с ними содержимого вкладок. Давайте добавим немного CSS:
[id^=tab] { position: absolute; } [id^=tab]:first-child { z-index: 1; } [id^=tab]:target { z-index: 2; }
Вот где происходит волшебство. Во-первых, мы абсолютно позиционировали все наши вкладки. Затем мы сделали нашу первую вкладку самым верхним слоем, добавив z-index: 1
. Это важно, только если вы хотите, чтобы первая вкладка в исходном порядке была первой вкладкой, которую увидят пользователи. Наконец, мы добавили z-index: 1
к нашей целевой вкладке. Это гарантирует, что целевой слой всегда будет самым верхним. Вы можете увидеть результат ниже.
Совет: улучшение доступности
Более доступная версия может также использовать JavaScript для переключения атрибутов hidden
или aria-hidden=true
зависимости от видимости каждого тела вкладки.
Нажатие на вкладку обновляет URL с новым идентификатором фрагмента документа. Это в свою очередь вызывает состояние :target
.
Отключение селекторов с помощью :not()
Возможно, самым мощным из этого нового поколения псевдоклассов является :not()
. Он возвращает все элементы, кроме тех, которые соответствуют аргументу селектора. Например, p:not(.message)
выбирает каждый элемент p
котором отсутствует класс message
.
Псевдокласс :not()
— это то, что называется функциональным псевдоклассом . Он принимает один аргумент, как и функции в других языках программирования. Любой аргумент, передаваемый :not()
должен быть простым селектором, таким как тип элемента, имя класса, идентификатор или другой псевдокласс. label.checkbox
потерпят неудачу, как и составные селекторы, такие как label.checkbox
или сложные селекторы, такие как p img
.
Вот пример формы, которая использует текстовые типы ввода и переключатели:
<form method="post" action="#"> <h1>Join the Cool Kids Club</h1> <p> <label for="name">Name:</label> <input type="text" id="name" name="name" required> </p> <p> <label for="email">Email:</label> <input type="email" id="email" name="email" required> </p> <fieldset> <legend>Receive a digest?</legend> <p> <input type="radio" id="daily" name="digest"> <label for="daily" class="label-radio">Daily</label> <input type="radio" id="weekly" name="digest"> <label for="weekly" class="label-radio">Weekly</label> </p> </fieldset> <button type="submit">Buy Tickets!</button> </form>
В HTML метки, связанные с типом radio
имеют .label-radio
. Мы можем использовать псевдокласс :not()
: для нацеливания на эти элементы без класса label-radio
, как показано на рисунке ниже:
label:not(.label-radio) { font-weight: bold; display:block; }
Вот более хитрый пример. Давайте создадим стили для ввода текста. К ним относятся типы ввода, такие как number
, email
и text
а также password
и url
. Но давайте сделаем это, исключив переключатель, переключатель и диапазон ввода. Ваш первый инстинкт может заключаться в использовании следующего списка селекторов:
([type=radio]), input:not([type=checkbox]), input:not([type=range]) { ... }
К сожалению, это не сработает, так как каждый селектор отменяет предыдущий. Это эквивалент ввода:
input:not([type=radio]){ ... } input:not([type=checkbox]) { ... } input:not([type=range]) {... }
Вместо этого нам нужно связать псевдоклассы our :not()
, чтобы они все фильтровали элемент input
: [4]
input:not([type=radio]):not([type=checkbox]):not([type=range]) { ... }
Использование псевдоклассов (и псевдоэлементов) без простого селектора эквивалентно использованию его с универсальным селектором. Другими словами :not([type=radio])
— это то же самое, что и *:not([type=radio])
. В этом случае каждый элемент, у которого отсутствует атрибут type
и значение radio
будет соответствовать ―, включая html
и body
. Чтобы предотвратить это, используйте :not()
с селектором, таким как имя класса, идентификатор или селектор атрибута. Кстати, это также верно для имен классов, идентификаторов и селекторов атрибутов: .warning
и [type=radio]
такие же, как *.warning
и *[type=radio]
.
Селекторы CSS Уровень 4 уточняет способ :not()
работает, так что он может принимать список в качестве аргумента, а не только простые селекторы. Вместо того, чтобы связывать псевдоклассы, как ранее, мы сможем использовать аргумент через запятую:
input:not([type=radio], [type=checkbox], [type=range]) { ... }
К сожалению, ни один крупный браузер пока не поддерживает это, так что используйте пока что цепочку.
[4] Селекторная цепочка ниже также будет соответствовать элементам [type=image]
, [type=reset]
, [type=color]
и [type=submit]
.