Bootstrap dropdown clipped by overflow:hidden container, how to change the container?

HtmlCssTwitter Bootstrap

Html Problem Overview


Using bootstrap, I have a dropdown menu(s) inside a div with overflow:hidden, which is needed to be like this. This caused the dropdowns to be clipped by the container.

My question, how can I solve this clipping issue, e.g. change the container of all dropdowns inside my project to be body, with lowest cost possible?

this is an example of the code: http://jsfiddle.net/0y3rk8xz/

Html Solutions


Solution 1 - Html

if anyone interested in a workaround for this, bootstrap dropdown has a show.bs.dropdown event you may use to move the dropdown element outside the overflow:hidden container.

$('.dropdown').on('show.bs.dropdown', function() {
  $('body').append($('.dropdown').css({
    position: 'absolute',
    left: $('.dropdown').offset().left,
    top: $('.dropdown').offset().top
  }).detach());
});

there is also a hidden.bs.dropdown event if you prefer to move the element back to where it belongs once the dropdown is closed:

$('.dropdown').on('hidden.bs.dropdown', function() {
  $('.bs-example').append($('.dropdown').css({
    position: false,
    left: false,
    top: false
  }).detach());
});

Here is a working example:

> http://jsfiddle.net/qozt42oo/32/

Solution 2 - Html

Change the div property to overflow:visible;, or Set Position:absolute; on .dropdown class like

.bs-example .dropdown{position:absolute;}

See the Working Code: http://jsfiddle.net/guruWork/3x1f8ng5/

Solution 3 - Html

My solution was to use static positioning on the dropdown. I had the dropdown inside a bootstrap table with overflow hidden.

<div class="table" style="overflow: hidden;">
  <div class="dropdown" style="position: static;">
    <div class="dropdown-menu">...</div>
  </div>
</div>

It didn't work with your fiddle, however. So I'm not sure if my solution had something to do with bootstrap tables. Regardless, perhaps it will give someone something new to try.

Solution 4 - Html

Ng Bootstrap >= 4.1.0 (Angular powered Bootstrap) solution:

For anyone struggling with the same issue, but using ng-bootstrap, here's a solution for you - use container="body" option in your ngbDropdown:

<div ngbDropdown container="body">
    <!-- Dropdown menu goes here -->
</div>

Solution 5 - Html

All the answers mentioned here didn't work for me, so I found another workaround:

$('.dropdown').on('shown.bs.dropdown', function () {
    const dropdown = $(this);
    setTimeout(function () {
        dropdown.find('.dropdown-menu').css({'top': dropdown.offset().top - $(window).scrollTop(), 'left': dropdown.offset().left - $(window).scrollLeft(), 'position': 'fixed'});
    }, 1);
});

The timeout is necessary as the event handler is fired before bootstraps sets the CSS of the dropdown therefore overwriting it

Solution 6 - Html

I had some kind of scroll problem with most of solutions in this and other questions I've seen on SO. What worked for me was making the dropdown position inherit:

.dropdown {
  position: inherit;
}

And then set the dropdown-menu position using JavaScript:

$(document).on("show.bs.dropdown", function () {
  var dropdownToggle = $(this).find(".dropdown-toggle");
  var dropdownMenu = $(this).find(".dropdown-menu");
  dropdownMenu.css({
    "top": (dropdownToggle.position().top + dropdownToggle.outerHeight()) + "px",
    "left": dropdownToggle.position().left + "px"
  });
});

Here is a working example: http://jsfiddle.net/ck66ee9q/

Solution 7 - Html

You can also try this one by replacing yourDivId by the id of your div.

$('.dropdown').on('show.bs.dropdown', function() {
    $('#yourDivId').css('overflow-x', 'visible');
});

$('.dropdown').on('hidden.bs.dropdown', function() {
    $('#yourDivId').css('overflow-x', 'hidden');
});

Solution 8 - Html

I was facing the same issue and after searching for hours.. I created a event handler to catch the dropdown-toggle and get the positions and attach it dynamically. so that it doesnt get cut off.

Here is the simple code I used. Try it out if this helps.

$('.dropdown-toggle').click(function (){
     dropDownFixPosition($('button'),$('.dropdown-menu'));
 });
 function dropDownFixPosition(button,dropdown){
    var dropDownTop = button.offset().top + button.outerHeight();
    dropdown.css('top', dropDownTop + "px");
    dropdown.css('left', button.offset().left + "px");
  }

Solution 9 - Html

All suggestions that have been made here have some kind of lacking things and I could not make them work properly. So I have made this one based on all suggestions and works great for me.

I have used another class here to make it different than regular dropdown elements that I might wanna have them run in the regular way.

$(document).on("show.bs.dropdown", ".dropdown.my-body-dropdown", function () {

    //original dropdown element
    var thisDropdown = $(this);
    
    //make a deep clone
    var thisDropdownCopy = thisDropdown.clone(true, true);

    //append to the body with a different class which is my-modified-dropdown here 
    //and open which will make dropdown menu show up
    $("body").append( thisDropdownCopy.addClass("my-modified-dropdown open").css({ "position": "absolute", "left": thisDropdown.offset().left, "top": thisDropdown.offset().top }).detach() );
    
    //hide the original dropdown element
    $(this).hide();
    
})
.on("hidden.bs.dropdown", ".dropdown.my-body-dropdown", function() {
    
    //remove modified dropdowns
    $(".dropdown.my-body-dropdown.my-modified-dropdown").remove();
    
    //show original dropdowns
    $(".dropdown.my-body-dropdown").show();
    
});

Solution 10 - Html

I had a div element with a Bootstrap panel class containing DevExpress ComboBoxes contained in div elements with Bootstrap col-lg classes.

I had a problem of the panel background color or border color bleeding to the div above. To resolve that I added overflow:hidden; to the panel but that caused the ComboBox's dropdown to be cut off. I added style="position: inherit" to those div elements within the panel containing the ComboBoxes and that solved the problem.

<div class="col-sm-12" style="position: inherit">
<div class="col-sm-4" style="position: inherit">
 <dx:aspxComboBox></dx:aspxComboBox>
</div>
</div>

This solution I found here.

Solution 11 - Html

I ended up using tippy.js insead of bootstrap dropdown, which solved this overflow:hidden parent problem, since dropdown can be located in body tag.

Solution 12 - Html

You all were very helpful to me in getting this figured out. In my case, the accepted answer did not work because my dropdowns are created in code-behind during ajax as GenericHtmlControls and therefor, do not exist at page load to hook the events with the .dropdown selector. Additionally, my pages can have many dropdowns dynamically added that are affected by this, as well as any number of other dropdowns that are NOT affected.

I added a unique css class (editModeModuleMenu) to the affected div(s) containing the actual menu and previously marked with .dropdown-menu, changed the event selector to window and scoped the function to ONLY select and alter the single dropdown in focus.

$(window).on('show.bs.dropdown', function (e) {
var el = $(e.target).closest('.editModeModuleMenu');
if (el.length == 0) return;
$('body').append(el.css({
    position: 'absolute',
    left: el.offset().left,
    top: el.offset().top
}).detach());})

And here is the relevant code-behind:

private void attachSettingGear(Panel container)
    {
        var dropdown = new HtmlGenericControl("div");
        dropdown.Attributes["class"] = "dropdown";
        dropdown.Style["position"] = "absolute";
        dropdown.Style["top"] = "2px";
        dropdown.Style["right"] = "10px";
        

        var a = new HtmlGenericControl("a");
        a.Attributes["href"] = "#";
        a.Attributes["class"] = "dropdown-toggle";
        a.Attributes["data-bs-toggle"] = "dropdown";
        a.Style["color"] = "white";
        dropdown.Controls.Add(a);
        

        var gear = new HtmlGenericControl("span");
        gear.Attributes.Add("class", "navBarIcon bi-gear");
        
        a.Controls.Add(gear);

        container.Style["position"] = "relative";
        container.Controls.Add(dropdown);

        var menu = new HtmlGenericControl("div");
        menu.Attributes["class"] = "dropdown-menu editModeModuleMenu";
        dropdown.Controls.Add(menu);

        createMenuLink(menu, "Delete", "trash3", $"javascript:popupConfirm('Confirm Delete','Are you sure you want to delete this module?', 'Delete', 'Cancel', deletePageModule, null, {ModuleSettings.ID})");
    }

private void createMenuLink(HtmlGenericControl menu, string text, string icon, string href)
    {
        var ico = new HtmlGenericControl("span");
        ico.Attributes.Add("class", "navBarIcon bi-" + icon);

        var item = new HtmlGenericControl("a");
        item.Attributes["class"] = "dropdown-item";
        item.Attributes["href"] = href;
        item.InnerText = text;
        item.Controls.AddAt(0, ico);

        menu.Controls.Add(item);
    }

Thank you all for the excellent information. I hope my addition helps someone else struggling with this.

Solution 13 - Html

I faced the same issue, with needing to have overflow:hidden set, but yet have the drop-down not be clipped.

However my situation involved the Bootstrap Carousel, so I decided a valid solution would make the overflow visible only when the dropdown is opened, and when it closes, the overflow can return to hidden. This solution might work for others, so I'm sharing it.

$('.dropdown-toggle').click(function() {
  var $container = $(this).parent('.carousel-inner');
  $container.css('overflow','visible');
  $(document).one('click', function() {
      $container.css('overflow','');
  });        
});

Note, this doesn't check for Esc key being used to close the dropdown, but in my case this wasn't an issue. My own version uses a class to apply the style which some devs might prefer instead of modifying inline CSS.

Solution 14 - Html

Changing the container is possible using jQuery e.g. $(".dropdown").insertAfter(".bs-example");

See this code for example: https://jsfiddle.net/SolveItSimply/pwmyvsw6/

I don't recommend this though, as you will lose any of the usefulness of Bootstrap positioning and keeping the drop-down elements in order will be messy.

Instead, you could use overflow:visible along with the 'hidden' class to your advantage, hiding any element that overflows with JavaScript. Here's an example: http://jsfiddle.net/SolveItSimply/z14c210x/

You will need to check the contained elements when the div is first visible and whenever the height of the container changes, which I've tried to demonstrate in my example.

Solution 15 - Html

I couldn't set the container to overflow:visible, but inserting a

<div class="clearfix" />

below the block containing the Dropdown solved the problem for me.

Solution 16 - Html

Just change the overflow value to visible.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlBaraa ShView Question on Stackoverflow
Solution 1 - HtmlVarolView Answer on Stackoverflow
Solution 2 - HtmlGuruView Answer on Stackoverflow
Solution 3 - HtmlJacob ColvinView Answer on Stackoverflow
Solution 4 - HtmlYulianView Answer on Stackoverflow
Solution 5 - HtmlJohannesView Answer on Stackoverflow
Solution 6 - HtmlHelder PereiraView Answer on Stackoverflow
Solution 7 - HtmlPILABRE MIKAILAView Answer on Stackoverflow
Solution 8 - HtmlChaitView Answer on Stackoverflow
Solution 9 - HtmlsimsekView Answer on Stackoverflow
Solution 10 - HtmlDov MillerView Answer on Stackoverflow
Solution 11 - HtmlGiedriusView Answer on Stackoverflow
Solution 12 - HtmlPlumbtricianView Answer on Stackoverflow
Solution 13 - Htmlmikeapr4View Answer on Stackoverflow
Solution 14 - HtmlChris DobsonView Answer on Stackoverflow
Solution 15 - HtmlAndreasView Answer on Stackoverflow
Solution 16 - Htmlsanjeev shettyView Answer on Stackoverflow