It seems you are in search of a solution that does not rely on CSS or layering of elements/siblings. If that's the case, I have come up with a method to create a custom mouseover/out functionality. This approach involves monitoring global mouse movements on the window and checking every ~17ms if we are moving across the boundaries of the designated element (I also included a custom event in case there are intricate nested elements involved, although it's not mandatory):
FIDDLE
To differentiate between various mouseover/out events, I've incorporated Math.random.
!function(){
var mark = document.getElementsByTagName("mark")[0],
mouseout = true,
mouseover = false,
customMouseEvent = new CustomEvent(
"customMouseEvent",
{
bubbles:false,
detail:{
mouseout:function(){return mouseout},
mouseover:function(){return mouseover}
}
}
);
mark._lastGesture = "mouseout";
window.addEventListener("mousemove",function(e){
if(mark._busy){return}
mark._busy = true;
window.requestAnimationFrame(function(){
var rect = mark._rect || (mark._rect = mark.getBoundingClientRect());
if(
(e.clientX - rect.left < rect.width)
&& (e.clientX - rect.left > 0)
&& (e.clientY - rect.top <= rect.height)
&& (e.clientY - rect.top > 0)
){
mouseout = false;
mouseover = true;
} else {
mouseout = true;
mouseover = false;
}
mark.dispatchEvent(customMouseEvent);
mark._busy = false;
setTimeout(function(){delete mark._rect},17);
});
});
mark.addEventListener("customMouseEvent",function(e){
if(e.detail.mouseover() && this._lastGesture !== "mouseover") {
this._lastGesture = "mouseover";
document.getElementById("feedback").textContent = "Mousover! " + Math.random();
} else if (e.detail.mouseout() && this._lastGesture !== "mouseout") {
this._lastGesture = "mouseout";
document.getElementById("feedback").textContent = "Mousout! " + Math.random();
}
})
}();