Псевдоклассы СSS :not() и :target
Сегодня мы рассмотрим менее распространенные псевдоклассы CSS, которые поддерживаются в современных браузерах: child-indexed и typed child-indexed, а также псевдоклассы для элементов ввода input. Псевдоклассы child-indexed и typed child-indexed позволяют выделять элементы по их расположению в дереве документа. Псевдоклассы input определяют поля формы на основе их значений и состояний.
Подсветка фрагментов страницы псевдоклассом :target
В этом случае идентификатор фрагмента является частью URL, который следует после хеша # (например, #top или #footnote1). Такое часто используется для организации навигации по странице при помощи так называемой «jump-link». С помощью псевдокласса :target можно подсветить фрагмент документа:
<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 получается результат, который приведен ниже:

Каждый comment в коде обозначен идентификатором, который позволяет ссылаться на конкретный фрагмент. Например, <a href="#comment-1146937891">. Всё что остаётся – это стилизовать комментарий, используя псевдокласс CSS child :target:
.comment:target {
background: #ffeb3b;
border-color: #ffc107
}
Когда идентификатор фрагмента в URL совпадает с комментарием (например, http://example.com/post/#comment-1146937891), он будет подсвечен жёлтым цветом, как показано ниже:

Псевдокласс CSS :target позволяет создавать комбинации, что открывает пространство для манёвров и позволяет не использовать JavaScript. Стилизуем наш пример с помощью 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 к нашей вкладке target. Это гарантирует, что выделенный слой всегда будет расположен поверх остального контента. Результат представлен ниже:

Улучшаем доступность
В более доступной версии (в том числе и псевдоклассах CSS ссылок) можно использовать JavaScript для переключения атрибутов hidden и aria-hidden=true.
Клик по вкладке обновляет URL с использованием нового идентификатора фрагмента, после чего приводится в действие состояние :target.
Отрицание селекторов при помощи :not()
Одним из самых многофункциональных считается псевдокласс :not(). Он возвращает все элементы, за исключением тех, которые совпадают с аргументом селектора. Например, p:not(.message) выделяет все элементы p без класса message.
Псевдокласс :not() принимает один аргумент, как и большинство функций в других языках программирования. Любой аргумент, заданный в :not(), должен быть простым селектором, названием класса или ID, другим псевдоклассом. Псевдоклассы не работают так, как составные селекторы типа label.checkbox или сложные селекторы типа p img.
Посмотрите на пример формы, в которой используется текстовые элементы ввода и radio buttons:
<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 label, ассоциированные с элементами типа radio, имеют класс .label-radio. Можно использовать псевдокласс CSS нажатия :not() для выделения элементов, не имеющих класса label-radio, как это показано на картинке ниже:
label:not(.label-radio) {
font-weight: bold;
display:block;
}

Рассмотрим более сложный пример. Используем стилизацию текстовых полей. Сюда входят элементы ввода number, email и text, а также password и url. Кроме этого мы исключим элементы radio, checkbox и range. Вам наверняка захочется воспользоваться следующим списком селектора:
([type=radio]),
input:not([type=checkbox]),
input:not([type=range]) {
...
}
К сожалению, это не поможет, так как каждый новый селектор переписывает предыдущий. Это всё равно, что писать:
input:not([type=radio]){ ... }
input:not([type=checkbox]) { ... }
input:not([type=range]) {... }
Вместо этого, нужно связать псевдоклассы :not() в цепочку, чтобы они отфильтровывали все элементы input:
input:not([type=radio]):not([type=checkbox]):not([type=range]) {
...
}
Приведённая цепочка селекторов также соответствует элементам [type=image], [type=reset], [type=color] и [type=submit]
Использование псевдоклассов и псевдоэлементов CSS без простого селектора эквивалентно его использованию с универсальным селектором. Другими словами, :not([type=radio]) – то же, что и *:not([type=radio]). В данном случае нашему критерию отвечает любой элемент без атрибута type и значения radio, включая html и body. Чтобы предотвратить это, используйте :not() с названием класса, ID или селектор атрибутов в качестве селектора.
В CSS Class-селекторах Level 4 изменен принцип работы :not(), так что, теперь он принимает в качестве аргумента не только простые селекторы, но и списки. Вместо того чтобы связывать классы, как это делалось раньше, можно указывать аргументы через запятую:
input:not([type=radio], [type=checkbox], [type=range]) {
...
}
К сожалению, пока далеко не все браузеры поддерживают этот вариант, поэтому мы рекомендуем и дальше использовать цепочки.