Мой прошлый ответ с хаком перестал работать в 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)
даст 0
round(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>