mouseenter vs mouseover
By FrontendPro Editorial Team Updated 9/26/2026
Answer
The difference is bubbling, and it decides how often your handler fires.
mouseover bubbles. It fires when the pointer enters the element or any of its descendants, so moving between children triggers it repeatedly.
mouseenter does not bubble. It fires once, when the pointer crosses into the element's boundary, and not again while moving around inside it.
<div id="card">
<img> <span>Label</span>
</div>
Moving the pointer across the card onto the image and then the span:
mouseoveron#card— fires three times (card, img, span)mouseenteron#card— fires once
Their partners behave the same way: mouseout bubbles, mouseleave does not.
Which to use
mouseenter / mouseleave for hover states on a component — a tooltip, a dropdown, a highlighted row. You want one clean enter and one clean exit, and mouseover would flicker as the pointer crosses internal elements.
mouseover / mouseout when you want delegation: one listener on a container reacting to whichever child is hovered, using event.target to identify it. This is the only option of the two for delegation, precisely because it bubbles.
The flicker bug
Using mouseout for "hide the tooltip" causes the tooltip to flash as the pointer moves between children. mouseleave fixes it in one change — this is by far the most common reason people learn the difference.
A detail
With mouseover, event.relatedTarget is the element the pointer came from, which lets you detect whether it arrived from outside or from a sibling inside. mouseenter rarely needs it, since it only fires on genuine boundary crossings.
Note these are mouse events; for touch and pen, use Pointer Events (pointerenter, pointerover), which follow the same bubbling rules.
