Від автора: стаття є витягом з книги CSS майстер за авторством Tiffany B. Brown. Книгу можна придбати в магазинах по всьому світу або придбати цифрову версію. Раніше в цій главі ми вже говорили, що псевдокласи дозволяють задавати стилі на основі інформації, яку неможливо отримати з дерева документа і на яку не можна послатися за допомогою простих селекторів. До них належать логічні та лінгвістичні псевдокласи типу :not :lang(), а також псевдокласи, що спрацьовують на власні події, типу :hover :focus.
У цьому розділі ми розглянемо таємні і маловідомі псевдокласи з упором на те, що є в браузерах: дочірні і типізовані дочірні псевдокласи, а також псевдокласи введення. Дочірні звичайні та дочірні типізовані псевдокласи дозволяють вибирати елементи на основі їх позиції в поддереве документа. Псевдокласи введення вибирають поля форм за їх значеннями і станів.
Виділення фрагментів сторінки з допомогою :target
Ідентифікатор фрагмента – це та частина URL, яка йде після символу #. Наприклад, #top або #footnote1. Ви могли їх використовувати для створення внутрішньої навігації по сторінці – так звані якорі. З допомогою :target можна виділити частину документа, що відноситься до цього фрагменту. І тут зовсім не потрібен JS.
Наприклад, у вас є кілька коментарів чи гілка дискусійного клубу:
Comments on this post
…
…
…
Додамо трохи CSS і всяких прикрас, і сторінка буде виглядати приблизно так.
У кожного коментаря в коді вище є свій ідентифікатор фрагмента. Тобто на кожен коментар можна отримати пряме посилання. Наприклад, . Залишилося лише поставити стилі коментаря з допомогою псевдокласу :target:
.comment:target {
background: #ffeb3b;
border-color: #ffc107
}
Коли в URL є ідентифікатор фрагмента, який посилається на коментар (наприклад, http://example.com/post/#comment-1146937891), коментар буде виділятися жовтим фоном, як на скріншоті нижче.
З :target можна використовувати будь-які стилі, що дозволяє створювати вкладки без підключення JS. Craig Buckler детально описав цю техніку в своєму уроці «як створити вкладки на чистому CSS3 з допомогою селектора :target». Ми трохи освіжити його спосіб, додамо трохи більше CSS3 властивостей. По-перше, давайте поглянемо на наш HTML:
Tab 2
Tab 3
-
This is tab 1.
-
This is tab 2
-
This is tab 3.
Досить проста розмітка. Тут є вкладки і контент для них. Додамо CSS:
[id^=tab] {
position: absolute;
}
[id^=tab]:first-child {
z-index: 1;
}
[id^=tab]:target {
z-index: 2;
}
А ось тут і криється вся магія. Наші вкладки мають абсолютне позиціонування. Далі ми поміщаємо першу вкладку на самий верх з допомогою z-index: 1. Дана властивість робить першу вкладку видимої за замовчуванням. В кінці ми додаємо z-index: 1 до нашої цільової вкладці. Так потрібна нам вкладка завжди буде лежати поверх інших. Результат представлений на скріншоті нижче.
Порада: підвищення доступності
Для більшої доступності можна використовувати JS, за допомогою якого буде встановлюватися атрибут hidden або aria-hidden=true залежно від видимості вкладок.
Клік по вкладці оновлює ідентифікатор фрагмента в URL, що в свою чергу викликає стан :target.
Віднімання з допомогою селекторів :not()
Псевдоклас :not(), можливо, самий потужний з нових. Він повертає всі елементи, крім тих, які вказані в аргументі. Наприклад, p:not(.message) вибере всі теги p без класу message.
Псевдоклас :not (), також відомий як функціональний псевдоклас. Він приймає один аргумент, як функції, в інших мовах програмування. Передається в :not() аргумент повинен бути простим селектором: тип елемента, клас, ID або інший псевдоклас. Псевдоклас не спрацює, якщо буде переданий складовою селектор типу label.checkbox або складний селектор типу p img.
Приклад форми з текстовими полями і радіокнопками:
Join the Cool Kids Club
Name:
Email:
Receive a digest?
Daily
Weekly
Buy Tickets!
В 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]) {… }
Замість цього необхідно зчепити псевдокласи :not(), щоб вони фільтрували поля вводу.
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]) {
…
}
На жаль, цей синтаксис на даний момент не підтримується ні в одному браузері. Поки що користуйтеся зв’язкою.