The mouseout event triggers when the mouse pointer leaves any child elements as well the selected element.
The mouseleave event is only triggered when the mouse pointer leaves the selected element.
Test this:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
x = 0;
y = 0;
$(document).ready(function(){
$("div.over").mouseout(function(){
$(".over span").text(x += 1);
});
$("div.enter").mouseleave(function(){
$(".enter span").text(y += 1);
});
});
</script>
</head>
<body>
<p>The mouseout event triggers when the mouse pointer leaves any child elements as well the selected element.</p>
<p>The mouseleave event is only triggered when the mouse pointer leaves the selected element. </p>
<div class="over" style="background-color:lightgray;padding:20px;width:250px;float:left">
<h3 style="background-color:white;">Mouseout event triggered: <span></span></h3>
</div>
<div class="enter" style="background-color:lightgray;padding:20px;width:250px;float:right">
<h3 style="background-color:white;">Mouseleave event triggered: <span></span></h3>
</div>
</body>
</html>
So as suggested by OLIVIERS this is a good solution:
<div x-data="{ open: false }" class="ml-4" @mouseleave="open = false">
<button @mouseover="open = true" class="border border-primary-900">Category</button>
<div x-show="open" class="h-80 bg-red-900">
<ul>
<li>Sub-category 1</li>
<li>Sub-category 2</li>
</ul>
</div>
</div>
The solution from Christopher is making use of the .away
modifier from alpine:
When the .away modifier is present, the event handler will only be executed when the event originates from a source other than itself, or its children.
This is useful for hiding dropdowns and modals when a user clicks away from them.
combined with the mouseover event