CSS Как с помощью операций min и max сделать сравнение ===
Я поставил перед собой задачу: хочу в CSS делать сравнения типа ===
У меня есть переменная percent от 0 до 1.
Я хочу создать переменную opacity, которая:
opacity = 1, если percent === 0
opacity = 0, если percent !== 0
Это правило нужно написать один выражением математическим, чтобы в CSS работало оно
Я уже научился делать вычисление модуля числа в CSS
Эту задачу нужно как-то решить с помощью функций min, max, abs (их в CSS я могу применить).
Ещё можно делать умножение, деление, складывать, вычитать.
Приложу пример кода, вот --opacity: max(var(--percent), 1); тут должно быть само вычисление
.card {
width: 150px;
height: 150px;
background-color: red;
--percent: 0;
--opacity: max(var(--percent), 1);
opacity: var(--opacity);
}
<div class="card"></div>
Ответы (3 шт):
Я удивлён, но благодаря Grundy, который предоставил ссылку на реализацию округления и не только, у меня получилось решить эту задачу.
В статье описывалось, что можно округлить CSS переменную как ceil, если сделать так:
@property --ceil {
syntax: '<integer>';
initial-value: 0;
inherits: false /* or true depending on context */
}
.my-elem {
--ceil: calc(var(--a) + 0.5)
}
То есть нужно указать переменной, что она integer, прибавить ей 0.5 и это будет работать как ceil округление. Но по факту у меня это не работало. Хотя может это баги хрома? Я просто прибавил не 0.5, а 0.49 и у меня всё начало работать
Можно это проверить, если в этом примере в браузере изменять CSS переменную percent, всё работает.
opacity = 1, если percent === 0
opacity = 0, если percent !== 0
@property --ceil {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.card {
width: 150px;
height: 150px;
background-color: red;
--percent: 0.1;
--ceil: calc(var(--percent) + 0.499);
--opacity: var(--ceil);
opacity: var(--opacity);
}
<div class="card"></div>
Мой прошлый ответ с хаком перестал работать в Chrome. Поэтому вот решение задачи с округлением на чистом CSS.
За чистое округление отвечает новая CSS функция round, которая работает во всех актуальных браузерах.
--percent: 0;
opacity: calc(1 - round(up, min(1, var(--percent)), 1));
min(1, var(--percent)) – ограничивает значение --percent, чтобы оно не превышало 1
round(up, min(1, var(--percent)), 1) - округляет значение вверх до ближайшего целого числа, аналог Math.ceil округления из JavaScript
- Например,
round(up, 0.85, 1)даст 1 round(up, 0, 1)даст 0round(up, 1, 1)даст 1
1 - round(...) - вычитается округленное значения
Ниже привёл пример, на котором можно проверить работу этого CSS
const inputSlider = document.querySelector(".input-slider");
const card = document.querySelector(".card");
const outputPercent = document.querySelector('.output__percent');
const outputOpacity = document.querySelector('.output__opacity');
inputSlider.addEventListener("input", () => {
const percent = inputSlider.value;
card.style.setProperty("--percent", percent);
renderOutputInfo();
});
renderOutputInfo();
function renderOutputInfo() {
const percent = getComputedStyle(card).getPropertyValue("--percent").trim();
const opacity = parseFloat(getComputedStyle(card).opacity);
outputPercent.innerText = percent;
outputOpacity.innerText = opacity;
}
.card {
width: 120px;
height: 120px;
background-color: red;
--percent: 0;
opacity: calc(1 - round(up, min(1, var(--percent)), 1));
}
<div class="card"></div>
<input class="input-slider" type="range" min="0" max="1" step="0.1" value="0">
<div class="output">
<div>
--percent:
<span class="output__percent"></span>
</div>
<div>
opacity:
<span class="output__opacity"></span>
</div>
</div>
UPDATE: Начиная с Chrome 137 можно использовать if в CSS. Теперь решение задачи визуально становится намного понятнее. Поддержка в браузерах
const inputSlider = document.querySelector(".input-slider");
const card = document.querySelector(".card");
const outputPercent = document.querySelector('.output__percent');
const outputOpacity = document.querySelector('.output__opacity');
inputSlider.addEventListener("input", () => {
const percent = inputSlider.value;
card.style.setProperty("--percent", percent);
renderOutputInfo();
});
renderOutputInfo();
function renderOutputInfo() {
const computedStyle = getComputedStyle(card);
const percent = computedStyle.getPropertyValue("--percent").trim();
const opacity = parseFloat(computedStyle.opacity);
outputPercent.innerText = percent;
outputOpacity.innerText = opacity;
}
.card {
width: 120px;
height: 120px;
background-color: red;
--percent: 0;
opacity: if(style(--percent: 0): 1; else: 0);
}
<div class="card"></div>
<input class="input-slider" type="range" min="0" max="1" step="0.1" value="0">
<div class="output">
<div>
--percent:
<span class="output__percent"></span>
</div>
<div>
opacity:
<span class="output__opacity"></span>
</div>
</div>