Условный CSS


Использование булевой логики для условного применения правил CSS, без JS

Благодарности

Прежде чем мы начнем, я должен поблагодарить Леа Вероу за ее доклад о секретах переменных CSS на CSS Day 2022, который вдохновил на создание этого поста, и за слайд-деск, который она любезно предоставила.

В своем докладе Леа осветила некоторые малоизвестные возможности пользовательских свойств CSS и рассказала о некоторых будущих усовершенствованиях. На слайде 58 Лиа упомянула о том, как можно выполнять логические операции для условного применения стиля с помощью простой арифметики. В этой заметке я планирую изучить эту концепцию немного глубже.

Введение

Существует три основных логических операции: NOT, AND и OR, все из которых работают с булевыми значениями TRUE или FALSE. Однако, за исключением псевдокласса checked, CSS не очень хорошо поддерживает булевы операции. Чтобы преодолеть это ограничение, мы будем использовать двоичные значения (1/0) вместо булевых значений (TRUE/FALSE) соответственно.

Мы изучим механику моделирования логических операций с помощью пользовательских свойств и продемонстрируем, как значения 1 и 0 помогут нам применить стилизацию. Перед этим мы кратко подтвердим наше понимание фактических логических операций, которые можно найти в большинстве языков программирования, таких как JavaScript.

Операция NOT («!» в JavaScript)

Операция NOT принимает одно входное значение и инвертирует его. True становится False, False становится True, или, в нашем случае, входное значение 1 приводит к выходу 0, а 0 in становится 1 out.

Операция AND («&&» в JavaScript)

Операции AND и OR принимают два (или более) входных сигнала и выдают один выходной. Операция AND выдает значение True только в том случае, если все входы True, в противном случае на выходе получается False. В наших «функциях» используются только два входа, только когда вход-A и вход-B равны 1, на выходе будет 1.

Операция ИЛИ («||» в JavaScript)

Операция ИЛИ дает на выходе TRUE, если любой вход TRUE, и FALSE, если все входы FALSE. Следующая таблица истинности иллюстрирует простое поведение.

Логические операции CSS

Для поддержки наших операций нам понадобятся некоторые дополнительные значения, определенные в контексте классов CSS следующим образом.
Булевы (двоичные) значения
Определите булевы значения True и False как 1 и 0.

.not-operation, .and-operation, .or-operation {
    --TRUE: 1;
    --FALSE: 0;
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Входные значения по умолчанию
Подготовьте входные значения для операций.

.not-operation, .and-operation, .or-operation {
    --INPUT: var(--TRUE);
    --INPUT-A: var(--FALSE);
    --INPUT-B: var(--TRUE);
}
Войти в полноэкранный режим Выход из полноэкранного режима

Логические операции

Используя следующие три основные операции, можно получить множество других операций, таких как NAND (НЕ И), NOR (НЕ ИЛИ), XOR и т.д.

НЕ

Используя числовые значения вместо булевых, операцию NOT можно получить путем вычитания входного значения (I) из 1. Когда I = 1, 1 — 1 = 0, когда I = 0, 1 — 0 = 1.

.not-operation {
    --OUTPUT: calc(1 - var(--INPUT));
}
Вход в полноэкранный режим Выход из полноэкранного режима

И

Снова используя 1 и 0, операция AND достигается путем умножения двух входов (I1 и I2).

Умножение значения на ноль дает ноль, поэтому только когда все (оба) входа равны единице, на выходе получается единица.

.and-operation, {
    --OUTPUT: calc(var(--INPUT-A) * var(--INPUT-B));
}
Вход в полноэкранный режим Выход из полноэкранного режима

ИЛИ

Наконец, у нас есть операция ИЛИ, которая является аддитивной с зажимом. Сложение двух входов (I1 & I2) приведет к результату:

Нам нужно зажать выход 1 + 1 от 2 до 1, что можно сделать двумя способами. Мы могли бы вычесть результат выполнения операции ADD на тех же входах, но CSS может помочь в этом с помощью функции ‘min’ следующим образом.

.or-operation {
    --OUTPUT: min(var(--INPUT-A) + var(--INPUT-B), 1);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Демонстрация

Для демонстрации описанных выше операций мы выведем результат с помощью CSS свойства content псевдоэлемента ::after элемента DIV с классом ‘result’.

.result::after {
    counter-reset: logic-result var(--OUTPUT);
    content: counter(logic-result);
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Операция [OPERATION], которую мы хотим выполнить, будет задана с помощью класса CSS. Входные значения будут задаваться путем присвоения соответствующего пользовательского свойства (-ise) через атрибут style.

Каждый тестовый пример будет иметь следующую форму.

<div class="result [OPERATION]" style="--INPUT: [BOOLEAN_VALUE]"></div>

<!-- or -->

<div class="result [OPERATION]"
  style="--INPUT-A: [BOOLEAN_VALUE_A] --INPUT-B: [BOOLEAN_VALUE_B]"></div>
Вход в полноэкранный режим Выход из полноэкранного режима

Вот тестовые примеры

<div class="result not-operation" style="--INPUT: var(--FALSE)"></div>
<div class="result not-operation" style="--INPUT: var(--TRUE)"></div>

<div class="result and-operation"
  style="--INPUT-A: var(--FALSE); --INPUT-B: var(--FALSE)"></div>
<div class="result and-operation"
  style="--INPUT-A: var(--FALSE); --INPUT-B: var(--TRUE)"></div>
<div class="result and-operation" 
  style="--INPUT-A: var(--TRUE); --INPUT-B: var(--FALSE)"></div>
<div class="result and-operation" 
  style="--INPUT-A: var(--TRUE); --INPUT-B: var(--TRUE)"></div>

<div class="result or-operation"
  style="--INPUT-A: var(--FALSE); --INPUT-B: var(--FALSE)"></div>
<div class="result or-operation"
  style="--INPUT-A: var(--FALSE); --INPUT-B: var(--TRUE)"></div>
<div class="result or-operation"
  style="--INPUT-B: var(--FALSE); --INPUT-A: var(--TRUE)"></div>
<div class="result or-operation"
  style="--INPUT-B: var(--TRUE); --INPUT-A: var(--TRUE)"></div>
Вход в полноэкранный режим Выйти из полноэкранного режима

Исходный код можно посмотреть в моем CodePen.

Оцените статью
devanswers.ru
Добавить комментарий