Tarik
Tarik

Reputation: 81721

How to keep Bootstrap dropdown always on top

We are using Bootstrap 3 Dropdown however, it looks like this when there is a horizontal scroll bar that the container div shows when the page is not big enough in width. Please aware that it is not the scroll bar of the browser window. The scrollbar clips the dropdown like below:

enter image description here

I have checked dropdown-menu which is associated with the ul element that is the dropdown and it looks fine to me:

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 1000;
  display: none;
  float: left;
  min-width: 160px;
  padding: 5px 0;
  margin: 2px 0 0;
  list-style: none;
  font-size: 15px;
  text-align: left;
  background-color: #ffffff;
  border: 1px solid #999999;
  border-radius: 4px;
  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  background-clip: padding-box;
}

Later I checked whether the container div has any z-index defined but I couldn't find any. But it has a class called table-responsive and it looks like this:

@media screen and (max-width: 1600px)
.table-responsive {
margin-bottom: 15px;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
}

Upvotes: 1

Views: 7357

Answers (1)

Tarik
Tarik

Reputation: 81721

I have found the answer. First of all, change btn-group's position css rule from relative to inherit.

$("#dropdownMenu").on("show.bs.dropdown", function () {
    // For difference between offset and position: http://stackoverflow.com/a/3202038/44852
    var dropdownButtonPosition = $(this).position();
    var dropdownButtonOffset = $(this).offset();
    var dropdownButtonHeight = $(this).height();
    var dropdownMenu = $(this).find(".dropdown-menu:first");
    var dropdownMenuHeight = dropdownMenu.height();
    var scrollToTop = $(document).scrollTop();

    // It seems there are some numbers that don't get included so I am using some tolerance for
    // more accurate result.
    var heightTolerance = 17;

    // I figured that window.innerHeight works more accurate on Chrome
    // but it is not available on Internet Explorer. So I am using $(window).height() 
    // method where window.innerHeight is not available.
    var visibleWindowHeight = window.innerHeight || $(window).height();

    var totalHeightDropdownOccupies = dropdownMenuHeight +
        dropdownButtonOffset.top + dropdownButtonHeight + heightTolerance - scrollToTop;

    // If there is enough height for dropdown to fully appear, then show it under the dropdown button,
    // otherwise show it above dropdown button.
    var dropdownMenuTopLocation = totalHeightDropdownOccupies < visibleWindowHeight
        ? dropdownButtonPosition.top + dropdownButtonHeight
        : dropdownButtonPosition.top - dropdownMenuHeight - dropdownButtonHeight + heightTolerance;

    dropdownMenu.css("left", dropdownButtonPosition.left)
        .css("top", dropdownMenuTopLocation);
});

Upvotes: 5

Related Questions