Assigning a gradient to an HTML element fails, if the string of CSS is generated in JS on runtime, but it does not if it's a string defined as constant. I want to generate a radial-gradient at the position of the cursor, but I simplified this example to only contain the lines of code required to cause the unwanted behaviour.
HTML:
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
JS (not working):
let divs = document.getElementsByClassName('buggy-gradient');
for(i = 0; i < divs.length; i++){
divs.item(i).addEventListener('mousemove', e => {
let gradient = 'radial-gradient(circle at ' + e.clientX + ' ' + e.clientY + ', blue, red)';
console.log(gradient);
e.target.style.background = gradient;
});
}
The console-log shows the CSS line as I want it, but assigning it apparently fails:
"radial-gradient(circle at 1044 325, blue, red)"
JS (working):
let divs = document.getElementsByClassName('buggy-gradient');
for(i = 0; i < divs.length; i++){
divs.item(i).addEventListener('mousemove', e => {
e.target.style.background = 'radial-gradient(circle at 0 0, blue, red)';
});
}
I made a pen: https://codepen.io/stairjoke/pen/poNgKbm
As a Stack Snippet:
let divs = document.getElementsByClassName('buggy-gradient');
for(i = 0; i < divs.length; i++){
divs.item(i).addEventListener('mousemove', e => {
let gradient = 'radial-gradient(circle at ' + e.clientX + ' ' + e.clientY + ', blue, red)';
console.log(gradient);
e.target.style.background = gradient;
// e.target.style.background = 'radial-gradient(circle at 0 0, blue, red)';
});
}
div {
height: 400px;
width: 400px;
background: radial-gradient(green, yellow);
display: inline-block;
margin: 5px;
}
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
The problem is that you don't have any units on your values. 0
is a special value, it doesn't require any units, but all other values do.
Adding px
solves the problem:
let gradient = 'radial-gradient(circle at ' + e.clientX + 'px ' + e.clientY + 'px, blue, red)';
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^−−−−−−−−−−−−−−−−−−^^
FWIW, I'd use a template literal:
let gradient = `radial-gradient(circle at ${e.clientX}px ${e.clientY}px, blue, red)`;
// −−−−−−−−−−−−^−−−−−−−−−−−−−−−−−−−−−−−−−−^^−−−−−−−−−^^^−^^−−−−−−−−−^^^−−−−−−−−−−−−^
let divs = document.getElementsByClassName('buggy-gradient');
for(i = 0; i < divs.length; i++){
divs.item(i).addEventListener('mousemove', e => {
let gradient = `radial-gradient(circle at ${e.clientX}px ${e.clientY}px, blue, red)`;
console.log(gradient);
e.target.style.background = gradient;
});
}
div {
height: 400px;
width: 400px;
background: radial-gradient(green, yellow);
display: inline-block;
margin: 5px;
}
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>