Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bootstrap dropdown menu overlap wrapping div

What is the proper way to allow a bootstrap button dropdown to overlap the containing div? The containing div has overflow-y:scroll. The current problem is when containing dropdown contents is displayed the contents stay within the scrollable div.

Tried using absolute positioning of dropdown, changing position css to fixed does allow the overlap. Is that the proper way?

Here is jsfiddle demonstrating: http://jsfiddle.net/weaver_je/pA6cx/1/

The first button (.btn1) with position: fixed is closest to desired output.

<div style="width:120px; height:150px; overflow-y:scroll;">
<div class="dropdown">
  <button class="btn dropdown-toggle btn1" type="button" id="dropdownMenu1" data-toggle="dropdown">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation" class="divider"></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
  </ul>
</div>

    <br/><br/>

<div class="dropdown">
  <button class="btn dropdown-toggle btn2" type="button" id="dropdownMenu1" data-toggle="dropdown">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation" class="divider"></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
  </ul>
</div>
</div>

$(".btn1").click(function (e) {         
    $(".dropdown-menu").css({
        position:"fixed",
        display: "block",
        left: e.pageX,
       top: e.pageY
    });

    return false;
});

$(".btn2").click(function (e) {           
    $(".dropdown-menu").css({
        position:"absolute",
        display: "block",
        left: e.pageX,
        top: e.pageY
    });

    return false;
});
like image 269
user3415339 Avatar asked Mar 13 '14 12:03

user3415339


3 Answers

One way to do this just by CSS:

Bootply : http://jsfiddle.net/pA6cx/2/

CSS :

body > div > div.dropdown.open {
position: absolute;
}

Just available for first button, I didn't edit the second...

After comment : Jsfiddle : http://jsfiddle.net/fw522/2/

body > div > div.dropdown.open:hover{
position: absolute;
}

Set to absolute position only when mouse is over

like image 73
BENARD Patrick Avatar answered Sep 21 '22 18:09

BENARD Patrick


I solved similar problem by moving the dropdown-toggle button outside the dropdown div, adding the data-target attribute to the button pointing to that div, and making the div's position absolute.

Here is jsfiddle: http://jsfiddle.net/pA6cx/58/

HTML

<button class="btn dropdown-toggle btn1" type="button" data-target="#dropdown1" id="dropdownMenu1" data-toggle="dropdown">
  Dropdown
  <span class="caret"></span>
</button>
<div class="dropdown" id="dropdown1">
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation" class="divider"></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
  </ul>
</div>

CSS

.dropdown {
  position: absolute;
}
like image 32
Helder Pereira Avatar answered Sep 25 '22 18:09

Helder Pereira


One solution is to use fixed positioning on the drop-down and set its position with JavaScript:

var dropdown = $element.find('.dropdown-menu');
var button = $element.find('.btn.dropdown-toggle');
function positionDropDown() {
    dropdown.css('top', button.offset().top - $(window).scrollTop() + button.outerHeight() + "px");
    dropdown.css('left', button.offset().left + "px");
}
button.click(positionDropDown);
dropdown.css('position', 'fixed');

One problem with this is when the user opens the drop-down and then scrolls the container. In that case, the dropdown will not follow the button.

To fix that, I guess one would have to bind to the scroll event of every container he finds up the DOM and update the dropdown position in the handler. An oversimplified example is this where we handle the window scroll only:

$(window).scroll(function(event) {
    positionDropDown();
});

Imagine doing that for every parent container of the dropdown in the DOM and you have the hack to make HTML and CSS work as it should in the first place...

like image 37
NoOne Avatar answered Sep 24 '22 18:09

NoOne