简体   繁体   中英

Bootstrap dropdown menu hidden behind other elements

I have a problem similar to this . But the solutions there does not work for my issue. And that discussion has been closed for further suggestions. Unfortunately I can't show my code exactly as it is on jsfiddle. However the issue is something like this . When trying to expand the dropdown inside first panel section, the dropdown hidden behind other elements. I've spent hours trying different suggestions concerning "stacking context", "position", and "z-index". I would really appreciate if anyone could point me to any resources that could help.

<div class="btn-group">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> <span data-bind="label">Select One</span>&nbsp;<span class="caret"></span>

                    </button>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Item 1</a>
                        </li>
                        <li><a href="#">Another item</a>
                        </li>
                        <li><a href="#">This is a longer item that will not fit properly</a>
                        </li>
                    </ul>
                </div>

You have two options. You can make the container's overflow expand to fit the content by setting 'overflow: auto' to the parent's css.

FIDDLE DEMO

.panel-body { /* parent container of the menu */
    overflow:auto;
}

Or you could do something functionally with JavaScript to handle the menu placement. This option is a little bit 'hacky' and would require further improvements. You would need to improve it to handle multiple menus open at once on the same page, and you would need to improve how it selects the menu. You might also want to add scroll support to move the menu with its target element unless that's not an issue. Here's the fiddle:

FIDDLE DEMO

(function() {
  // hold onto the drop down menu                                             
  var dropdownMenu;

  // and when you show it, move it to the body                                     
  $(window).on('show.bs.dropdown', function(e) {

    // grab the menu        
    dropdownMenu = $(e.target).find('.dropdown-menu');

    // detach it and append it to the body
    $('body').append(dropdownMenu.detach());   

    // grab the new offset position
    var eOffset = $(e.target).offset();

    // make sure to place it where it would normally go (this could be improved)
    dropdownMenu.css({
        'display': 'block',
        'top': eOffset.top + $(e.target).outerHeight(),
        'left': eOffset.left
    });                                                
  });

  // and when you hide it, reattach the drop down, and hide it normally                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})(); 

There is probably a better way to do this, but the concept is to move the menu from the confines of the parent element to the body. When you're relying on the html data-attributes to setup the menu, you'll have trouble doing this, but that is where the second solution I reference becomes useful.

Sadly I would have suggested looking into the 'Via Javascript' options that bootstrap provides, but apparently they don't have the option to set the target append element. It would have been nice to have an option to append the menu on to whichever element you want like most of their other items: Bootstrap Docs


EDIT

As @Andrea Pizzirani mentioned, you could try removing the css for the menu absolute positioning, but I wouldn't recommend it! That will mess up all other instances of the menu unless you add other css to restrict scope of the change. Also, if you want the menu positioned under the button, you'll have to redo CSS that bootstrap already had in place.

Still, if it works, and you're not worried about messing up all other menus, it may be the solution you were looking for. Heres a fiddle demonstrating the solution:

FIDDLE DEMO

dropdown-menu {}

EDIT I finally found where I originally found this solution. Gotta give credit where credit is due!

Try to remove position: absolute; from:

dropdown-menu {}

and place the menu under the button by css.

Modification of Jonathan's answer above, which was a huge help, but I modified it to place the menu back at it's source row, which allows custom jQuery to function properly (because the menu still exists at its initial parent element hierarchy. My use case was a jQuery DataTable with frozen columns. We had a bootstrap 4 "Action" dropdown-menu embedded in a cell of that table. The menu was appearing behind the hidden columns. This function allowed it be copied and pasted above the fixed columns where users can actually interact with it.

function BringActionMenuToForeground() {
    var dropdownMenu;

    /// When you show the menu, remove it from its current row and place it right back. This puts it on top of the DOM.
    $(window).on('show.bs.dropdown', function (e) {
        /// grab the menu
        dropdownMenu = $(e.target).find('.dropdown-menu');
        /// get the row where the menu appers.
        var menuRow = $(dropdownMenu).closest("tr");
        /// detach it and append it right back to the row from which it was taken.
        $(menuRow).append(dropdownMenu.detach());

        /// grab the new offset position
        var eOffset = $(e.target).offset();

        /// make sure to place it where it would normally go (this could be improved)
        dropdownMenu.css({
            'display': 'block',
            'top': eOffset.top + $(e.target).outerHeight(),
            'left': eOffset.left
        });
    });

    /// and when you hide it, reattach the drop down, and hide it normally                                                   
    $(window).on('hide.bs.dropdown', function (e) {
        $(e.target).append(dropdownMenu.detach());
        dropdownMenu.hide();
    });
}

Add an additional class on your HTML and use the below codepen reference code.

check here: https://codepen.io/qpqinc/pen/yLyPVMJ

You need to add only:

.panel.panel-default{
      overflow: inherit !important;
    }

JSFIDDLE DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM