У CSS насправді вже є логіка булевого типу, хоча й реалізована інакше, ніж звикли бачити розробники в інших мовах програмування. Справжнього булевого типу даних мова поки не має, але вже зараз можна застосовувати принципи true/false для побудови логіки та прапорців у стилях.
Булевий тип зазвичай позначає одне з двох станів: увімкнено або вимкнено, 0 або 1, а найчастіше - true або false.
Ключові слова true та false
У CSS справді існують ключові слова true і false. Найімовірніше, ви вже стикалися з ними під час роботи з @property, де параметр inherits приймає саме ці значення.
@property --myProperty {
inherits: true;
}
Щоб зберігати й гнучко використовувати ці значення, зручно застосувати кастомні властивості CSS, також відомі як CSS-змінні.
--isTrueOrFalse: true;
Варто зробити цю конструкцію суворішою: зареєструвати кастомну властивість --isTrueOrFalse так, щоб вона могла приймати лише одне з двох значень. Це можливо завдяки правилу @property, яке підтримує синтаксис перелічення ключових слів.
@property --isTrueOrFalse {
syntax: "true | false";
}
Далі задається початкове значення властивості.
@property --isTrueOrFalse {
syntax: "true | false";
initial-value: false;
}
Крім того, можна заборонити успадкування цієї властивості дочірніми елементами.
@property --isTrueOrFalse {
syntax: "true | false";
initial-value: false;
inherits: false;
}
У результаті --isTrueOrFalse стає зареєстрованою кастомною властивістю, яка зберігає лише true або false, за замовчуванням дорівнює false і не передається нащадкам. Це не справжній булевий тип, однак він достатньо точно його імітує для практичних задач.
Таку властивість можна застосувати для умовного стилювання:
@container style(--isTrueOrFalse: true) {
}
Перевіримо, як це працює на реальному прикладі.
Приклад застосування
Уявімо каталог сумок, товари в якому потрібно фільтрувати за типом: рюкзаки, спортивні сумки або обидва варіанти одразу.
Для фільтрації використовуються два чекбокси - «Backpacks» (рюкзаки) та «Duffel bags» (спортивні сумки). Логіка має бути такою: позначення «Backpacks» залишає лише рюкзаки, позначення «Duffel bags» - лише спортивні сумки, а якщо позначені обидва пункти, показуються і рюкзаки, і спортивні сумки, тоді як решта товарів приховується.
Реєстрація кастомних властивостей
Замість того, щоб перелічувати всі можливі комбінації станів :checked та :not(:checked) для чекбоксів і захаращувати селектори, зручніше підмінити ці стани значеннями true або false.
Нереєстровані кастомні властивості теж працюють, однак варто налаштувати саме зареєстровані - заради типобезпеки, продуктивності та контролю над успадкуванням.
@property --isBackpack {
syntax: "true | false";
inherits: false;
initial-value: false;
}
@property --isDuffel {
syntax: "true | false";
inherits: false;
initial-value: false;
}
За замовчуванням обидві властивості мають значення false. Коли користувач позначає чекбокс фільтра, відповідна властивість змінюється на true в якомусь елементі-предку. Підійде будь-який зручний предок, у цьому прикладі обрано :root.
:root {
&:has(#isBackpack:checked) {
--isBackpack: true;
}
&:has(#isDuffel:checked) {
--isDuffel: true;
}
}
Оскільки ці зареєстровані властивості потрібно буде перевіряти у значно глибшому нащадку, елементу :root варто надати ім'я контейнера, щоб потім посилатися на нього у запиті.
:root {
container-name: root;
&:has(#isBackpack:checked) {
--isBackpack: true;
}
&:has(#isDuffel:checked) {
--isDuffel: true;
}
}
Примітка: призначати ім'я контейнера не обов'язково, якщо кастомні властивості встановлюються у безпосередньому батьківському елементі того, де застосовується контейнерний запит, або якщо вони успадковуються.
Контейнерні запити
Усередині #productsList, де розміщені всі товари, частину сумок потрібно приховати залежно від того, який чекбокс (або обидва) активовано.
Застосування @scope тут не є обов'язковим, але воно допомагає ізолювати елементи усередині #productsList.
@scope(#productsList) {
@container root style(--isBackpack: true) and style(--isDuffel: true) {
li:not(.backpacks, .duffels) {
display: none;
}
}
@container root style(--isBackpack: true) and style(--isDuffel: false) {
li:not(.backpacks) {
display: none;
}
}
@container root style(--isBackpack: false) and style(--isDuffel: true) {
li:not(.duffels) {
display: none;
}
}
}
Запити @container style перевіряють значення --isBackpack та --isDuffel кореневого елемента. Залежно від комбінації true і false, з сітки товарів вилучається певна група сумок.
Ключові слова true та false наочно показують стан елементів фільтра, а їхнє застосування у запитах стилю зберігає цю наочність навіть у комбінованому стані кількох умов одразу.
Подібні сценарії можуть скористатися ключовими словами true та false, зберігаючи їх у кастомній властивості - зареєстрованій або ні. Автор матеріалу рекомендує саме зареєстрований варіант.
Підсумовуючи: ключові слова true та false дозволяють будувати зрозумілі вирази для контейнерних запитів і роблять складені умови набагато читабельнішими.
Джерело: Master.dev Blog



