As other people have noted, your original problem is that mouseover
and mouseout
events also fire for child elements. The solution to that issue is either to use jQuery's mouseenter
and mouseleave
events, or simply to replace the JS code with the CSS :hover
pseudo-class.
However, the reason why the other JS and CSS solutions posted here sometimes behave erratically (causing the square to disappear if you move the mouse over it slowly, but not if you move it fast, and not on all browsers even if you move it slowly) is because, depending on your browser and font settings, there may or may not be a small gap between the top line of text and the square below it. If the gap exists, and your mouse cursor hits it while moving from the text to the square, the browser will consider the mouse to have left the parent element, and will thus hide the square.
Setting a (light blue) background color on the parent element shows the issue clearly; depending on what font and line height the browser chooses, the parent element and the box can look like this:

or like this:

Manually setting a particularly large line height makes the problem easily reproducible (CSS example based on Thomas van Broekhoven's answer):
.kvadrat {
display: none;
}
.parent:hover > .kvadrat {
display: inline-block;
background-color: red;
width: 50px; height: 50px;
}
.parent {
line-height: 2.0;
background: lightblue;
}
<span class="parent">Hover mouse over this text!<br>
Here's another line of text.<br>
<span class='kvadrat'></span></span>
There are two general ways to fix this issue. The simplest option, where practical, is to make the parent element a block, thereby eliminating the gaps between the lines. You may also wish to add position: absolute
to the square's style, so that it won't expand its parent element when it appears:
.kvadrat {
display: none;
}
.parent:hover > .kvadrat {
display: inline-block;
position: absolute;
background-color: red;
width: 50px; height: 50px;
}
.parent {
display: block;
line-height: 2.0;
background: lightblue;
}
<span class="parent">Hover mouse over this text!<br>
Here's another line of text.<br>
<span class='kvadrat'></span></span>
Alternatively, if you really want to stick with an inline parent element (e.g. because you want it to be able to wrap across several lines of text), you can set a negative top margin on the square to make sure it overlaps the line of text above it. If you don't want the square to visibly overlap the text, you can further move all the visible content of the square into an inner element and set a corresponding positive top margin on it, like this:
.kvadrat {
display: none;
}
.parent:hover > .kvadrat {
display: inline-block;
position: absolute;
margin-top: -1em;
border: 1px dashed gray; /* to show the extent of this otherwise invisible element */
}
.kvadrat > .inner {
display: block;
margin-top: 1em;
background-color: red;
width: 50px; height: 50px;
}
.parent {
line-height: 2.0;
background: lightblue;
}
<span class="parent">Hover mouse over this text!<br>
Here's another line of text.<br>
<span class='kvadrat'><span class='inner'></span></span></span>