Псевдоклассы CSS: :not и :target

Псевдоклассы CSS: :not и :target

От автора: статья является выдержкой из нашей книги CSS мастер за авторством Tiffany B. Brown. Книгу можно купить в магазинах по всему миру или приобрести цифровую версию. Ранее в этой главе мы уже говорили, что псевдоклассы позволяют задавать стили на основе информации, которую невозможно получить из дерева документа и на которую нельзя сослаться с помощью простых селекторов. К ним относятся логические и лингвистические псевдоклассы типа :not и :lang(), а также псевдоклассы, срабатывающие на пользовательские события, типа :hover и :focus.

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

Выделение фрагментов страницы с помощью :target

Идентификатор фрагмента – это та часть URL, которая идет после символа #. Например, #top или #footnote1. Вы могли их использовать для создания внутренней навигации по странице – так называемые якоря. С помощью :target можно выделить часть документа, относящуюся к этому фрагменту. И тут совсем не нужен JS.

Например, у вас есть несколько комментариев или ветка дискуссионного клуба:

<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 и всяких украшений, и страница будет выглядеть примерно так.

Псевдоклассы CSS: :not и :target

У каждого комментария в коде выше есть свой идентификатор фрагмента. То есть на каждый комментарий можно получить прямую ссылку. Например, <a href=»#comment-1146937891″>. Осталось лишь задать стили комментария с помощью псевдокласса :target:

.comment:target {
  background: #ffeb3b;
  border-color: #ffc107
}

Когда в URL есть идентификатор фрагмента, ссылающийся на комментарий (например, http://example.com/post/#comment-1146937891), комментарий будет выделяться желтым фоном, как на скриншоте ниже.

Псевдоклассы CSS: :not и :target

С :target можно использовать любые стили, что позволяет создавать вкладки без подключения JS. Craig Buckler подробно описал эту технику в своем уроке «как создать вкладки на чистом CSS3 с помощью селектора :target». Мы немного освежим его способ, добавим чуть больше 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 к нашей целевой вкладке. Так нужная нам вкладка всегда будет лежать поверх остальных. Результат представлен на скриншоте ниже.

Псевдоклассы CSS: :not и :target

Совет: повышение доступности

Для большей доступности можно использовать JS, с помощью которого будет устанавливаться атрибут hidden или aria-hidden=true в зависимости от видимости вкладок.

Клик по вкладке обновляет идентификатор фрагмента в URL, что в свою очередь вызывает состояние :target.

Вычитание селекторов с помощью :not()

Псевдокласс :not(), возможно, самый мощный из новых. Он возвращает все элементы кроме тех, которые указаны в аргументе. Например, p:not(.message) выберет все теги p без класса message.

Псевдокласс :not() также известен как функциональный псевдокласс. Он принимает один аргумент, как функции в других языках программирования. Передаваемый в :not() аргумент должен быть простым селектором: тип элемента, класс, ID или другой псевдокласс. Псевдокласс не сработает, если будет передан составной селектор типа 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;   
}

Псевдоклассы CSS: :not и :target

Этот пример поинтереснее. Давайте стилизуем текстовые поля. К таким полям относятся инпуты с типом 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]) {... }

Вместо этого необходимо сцепить псевдоклассы :not(), чтобы они все фильтровали поля input.

input:not([type=radio]):not([type=checkbox]):not([type=range]) {
...
}

Использовать псевдокласс или псевдоэлемент без простого селектора – это то же самое, что использовать его с универсальным селектором. То есть запись :not([type=radio]) равна *:not([type=radio]). В таком случае в выборку попадут все элементы без атрибута type и значения radio, в том числе html и body. Чтобы исключить это, используйте :not() с классом, ID или селектором атрибута. Кстати, это касается и классов, ID и селекторов атрибутов: .warning и [type=radio] равны *.warning и *[type=radio] соответственно.

Спецификация CSS Selectors Level 4 улучшает принцип работы :not(). Теперь он может принимать список аргументов, а не просто селекторы. Вместо сцепки можно использовать запятую в качестве разделителя в аргументе:

input:not([type=radio], [type=checkbox], [type=range]) {
...
}

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

Автор: Tiffany Brown

Источник: https://www.sitepoint.com/

Редакция: Команда webformyself.

Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree