Some hover-to-expand elements flicker — opening and closing many times a second while the cursor sits perfectly still. Hover the Before on the left to feel it; the After on the right is the same thing, fixed.
Why it happens
The animation and the hover detection are fighting over the same element:
- You hover the element.
:hoverbecomes true. - A reveal animation scales it from
scale(0.9), shrinking it inward. - The shrinking box pulls its edge out from under the cursor.
:hoverflips to false → it collapses → the cursor is back over it →:hovertrue again.
The thing listening for :hover is the thing moving out from under the pointer. That’s the loop.
The fix
Separate the hover target from the animated element. A stable outer element owns :hover and only changes layout (width); an inner child carries the transform.
/* Stable hover target — never transforms */
.trigger { width: 36px; }
.trigger:hover { width: 260px; }
/* Inner element does the moving */
.trigger:hover .card {
animation: reveal 200ms ease-out;
}
@keyframes reveal {
from { transform: scale(0.9); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
This works because a transform on a child never changes its parent’s layout box. The outer trigger keeps its full footprint, so the cursor stays inside it and :hover never drops.
Takeaway
If a hover animation flickers, check whether the animated element is also the hover target. Keep “what listens for hover” and “what moves” on separate elements.