htmlcsshovermouseoverscrollbars

Allow element to appear over scrollbars


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.


Solution

  • 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:

    JSFIDDLE DEMO

    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
    

    JSFIDDLE DEMO WITH jQUERY