Is it possible to specify a <hue-interpolation-method> for anything other than gradients; specifically: transitions or animations?
.box {
width: 300px;
height: 50px;
}
.box.gradient {
background: linear-gradient(90deg in hsl longer hue, red, blue);
}
.box.transition {
background: red;
transition: 1s all;
}
.box.transition:hover {
background: blue;
}
.box.animation {
animation-name: color;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes color {
0% {
background: red;
}
100% {
background: blue;
}
}
Linear-gradient using hue interpolation:
<div class="box gradient"></div>
<br><br>
Transition (hover) -- how do I get it to use the hue interpolation?
<div class="box transition"></div>
<br><br>
Animation -- how do I get it to use the hue interpolation?
<div class="box animation"></div>
There is an active discussion to add a transition-interpolation
property that should cover it, but it's not yet ready.
One other property that does use the<hue-interpolation-method>
is the color-mix()
function, which actually has even better browser support than in gradients.
However to animate this is not that easy.
One way is to define @property
variables that we'll use as the percentage parameters of color-mix
and animate the custom variables instead.
@property --red {
syntax: "<percentage>";
inherits: false;
initial-value: 100%;
}
@property --blue {
syntax: "<percentage>";
inherits: false;
initial-value: 0%;
}
.box {
width: 300px;
height: 50px;
--red: 100%;
--blue: 0%;
background: color-mix(in hsl longer hue, red var(--red), blue var(--blue));
transition-duration: 2s;
/* Do not set background-color here ! */
transition-property: --red, --blue;
}
.box.transition:hover {
--red: 0%;
--blue: 100%;
}
.box.animation {
animation: anim 2s infinite;
}
@keyframes anim {
from {
--red: 100%;
--blue: 0%;
}
to {
--red: 0%;
--blue: 100%;
}
}
transition<div class="box transition"></div>
animation<div class="box animation"></div>
For browsers that don't support the @property
rule and thus animating custom variables (basically Gecko based browsers), you can create an animation with a lot of keyframes:
const FPS = 60;
const duration = 2000;
const frames = FPS / (1000 / duration);
const keyframes = Array.from({ length: frames }, (_, i) => {
const start = (i / frames) * 100;
const end = 100 - start;
return {
background: `color-mix(in hsl longer hue, red ${end}%, blue ${start}%)`
};
});
document.querySelector(".transition").addEventListener("mouseenter", (evt) => {
const anim = evt.target.getAnimations()[0];
if (anim) {
anim.reverse();
} else {
evt.target.animate(
keyframes,
{ duration, iterations: 1, fill: "forwards" }
);
}
});
document.querySelector(".transition").addEventListener("mouseout", (evt) => {
const anim = evt.target.getAnimations()[0];
if (anim) {
anim.reverse();
}
});
document.querySelector(".animation").animate(
keyframes,
{ duration, iterations: Infinity }
);
.box {
width: 300px;
height: 50px;
background: red;
}
transition<div class="box transition"></div>
animation<div class="box animation"></div>