I am trying to build a mouse-over-menu that appears when hovering over an element. This works great, however, for the bottom-rows the hover disappears in the scroll-bars.
HTML
<div style="width:1024px; height:50px; overflow:scroll; border: 1px solid red;">
<div class="dropdown">
<span style="margin-left:5px" class="checkboxlink ignore"></span>
<ul>
<li><a href="#"><span class="checkboxlink todo"></span>Te doen</a></li>
<li><a href="#"><span class="checkboxlink done"></span>Behandeld</a></li>
<li><a href="#"><span class="checkboxlink ignore"></span>Negeren</a></li>
<li><a href="#"><span class="checkboxlink park"></span>Parkeren</a></li>
</ul>
</div>
.... more divs
CSS
.dropdown{
position: relative;
display: inline-block;
font-size: 16px;
width: 40px;
border: 0px solid white;
vertical-align: top;
}
.dropdown:hover
{
border: 0px solid #ccc;
}
ul{
position: absolute;
list-style: none;
text-align: left;
z-index: 1;
margin:0;
padding:0;
display: none;
background-color: white;
border: 1px solid #ccc;
}
.dropdown:hover ul {
display: block;
}
See also here:
https://jsfiddle.net/w030L59t/
I tried positioning absolute, but the element still stays in the scrollable area.
The problem is any position: relative
attribute for the dropdown parents. If you remove them, you can easily add position: absolute
to your dropdown, to display it above the scrollable box:
The problem removing position: relative
is that the position of each dropdown is calculated once on page load. While the dropdowns work great without scrolling, you will notice in the demo, that each dropdown does not refresh its position.
This could be solved using a few lines of javascript, calculating the .offset.top
of each parent after scrolling and updating the dropdowns position using top: <offset.top of its parent>
. I have added the classes .list_item
and ul.dropdown_list
, although the ID #wrapper
.
$(document).ready(function() {
// fire function everytime the wrapper is scrolled
$('#wrapper').scroll(function(){
// set element to relate to
var list_items = $('div.list_item');
// get each position
list_items.each(function() {
// store offset().top inside var
var list_item_position = $(this).offset().top;
// select previous dropdown_list item
$(this).prev().find('ul.dropdown_list').css({
// apply offset top
top: list_item_position + "px"
});
});
// write to console to track changes
console.log('positions updated');
}); // .scroll
}); // document.ready