The problem is that elements are blocking the mouse such that elements in the background do not receive the event. With the exception that events bubble to the parent.
Given that you could change your markup slightly to get this effect.
First add a class to your boxes so we can easily find them in JavaScript:
<div class="box"></div>
<div class="box second"></div>
Then adapt the CSS such that this background change is toggled with a class instead:
.box.hovered {
background-color: yellow;
}
And then the JavaScript:
// Get all box elements
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
// For each box attach a listener to when the mouse moves
box.addEventListener('mousemove', (ev) => {
// Get the position of the mouse
const { x, y } = ev;
boxes.forEach(b => {
// for each box get it's dimension and location
const rect = b.getBoundingClientRect();
// check if the pointed is in the box
const flag = x > rect.left && x < rect.right && y > rect.top && y < rect.bottom;
// toggle the class
b.classList.toggle('hovered', flag);
});
});
});
This can be improved a lot, especially if you have more boxes by getting the rectangles beforehand and then using the index in the forEach
to link the box to it's rectangle:
const boxes = document.querySelectorAll('.box');
const rects = [...boxes].map(box => box.getBoundingClientRect());
Another improvement is to use the fact that events bubble to the parent, that means you could wrap all boxes in one parent and only add a listener to this parent.