19

I am trying to add a dropdown setting menu to my comments section in a project that I've been working on.

The dropdown menu seems to cut itself off and I am not sure why is that the case.

I tried overflow:visible and z-index:999. but none of them seem to work.

This is a basic comment block that I am trying to include a dropdown in

This is the basic code that I am trying to Implement

<div class="media">
    <a class="pull-left" href="/user/{{shared_scribble.scribble.user.username}}/"><img class="media-object" src="/img.png/"></a>
    <div class="dropdown pull-right">
        <a class="btn dropdown-toggle" data-toggle="dropdown" href="#" style="font-size:10px;padding: 4px 8px;">
            <b data-icon="&#xe001;"></b> <b class="caret"></b>
        </a>
        <ul class="dropdown-menu">
            <li><a href="#"><i class="icon-pencil"></i> Edit</a></li>
            <li><a href="#"><i class="icon-trash"></i> Delete</a></li>
            <li><a href="#"><i class="icon-ban-circle"></i> Ban</a></li>
            <li class="divider"></li>
            <li><a href="#"><i class="i"></i> Make admin</a></li>
        </ul>
    </div>
    <div class="media-body">
        <h4 class="media-heading"><a class="username" href="/user/hi/">Test User</h4>
        <p>
            Main body of the comment
        </p>
    </div>
</div>

And this is how my dropdown menu is turning out to be

ScreenShot

media CSS

.media,
.media-body {
  overflow: hidden;
  *overflow: visible;
  zoom: 1;
}
.media,
.media .media {
  margin-top: 15px;
}
.media:first-child {
  margin-top: 0;
}
.media-object {
  display: block;
}
.media-heading {
  margin: 0 0 5px;
}
.media .pull-left {
  margin-right: 10px;
}
.media .pull-right {
  margin-left: 10px;
}
.media-list {
  margin-left: 0;
  list-style: none;
}
Community
  • 1
  • 1
Jonathan
  • 2,728
  • 10
  • 43
  • 73

7 Answers7

25

This is not an ideal solution as the menu will not scroll with the target element, but I'm doing this for a scrolling data table as a last resort until I can find an alternative:

(function() {                                             
  var dropdownMenu;                                     
  $(window).on('show.bs.dropdown', function(e) {        
    dropdownMenu = $(e.target).find('.dropdown-menu');
    $('body').append(dropdownMenu.detach());          
    dropdownMenu.css('display', 'block');             
    dropdownMenu.position({                           
      'my': 'right top',                            
      'at': 'right bottom',                         
      'of': $(e.relatedTarget)                      
    })                                                
  });                                                   
  $(window).on('hide.bs.dropdown', function(e) {        
    $(e.target).append(dropdownMenu.detach());        
    dropdownMenu.hide();                              
  });                                                   
})();                  

This will append the menu to the body and clean it up on hide. I'm using jquery UI for positioning but you can replace it with regular jquery positioning if you don't want to add the heavy dependency. You may also want to alter $(window).on if you only want to do this to a limited selection of dropdowns.

Nick Perez
  • 259
  • 3
  • 2
  • Thanks Nick for the answer.. Worked well for me. I did not have the luxury being able to change the invisibility overflow (required fixed height/width) – bashar Jun 09 '15 at 23:35
  • Will love to see this answer updated to handle table scrolls too – Zia Ul Rehman Mughal Dec 02 '16 at 06:11
  • Works great, Thanks! Just change the `right` to `left` on `'my': 'left top', 'at': 'left bottom'` otherwise the menu will open in a wrong direction. – Roy Shoa Jan 26 '17 at 10:02
22

Check whether media class is has overflow:hidden. If so, replace it with overflow: auto or overflow: visible.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Gopikrishna
  • 857
  • 1
  • 8
  • 14
  • 4
    In some cases the `overflow:hidden` is required related to the design, @Nick Perez answer can help in those cases. – Roy Shoa Jan 26 '17 at 10:28
  • 1
    Agree with @RoyShoa, this is often not possible. Found workaround here: https://stackoverflow.com/questions/31829312/bootstrap-dropdown-clipped-by-overflowhidden-container-how-to-change-the-conta – Maxim Aug 01 '17 at 19:37
8

Write like this:

.media,
.media-body {
  overflow: visible;
}

.media:after,
.media-body:after{
 content:'';
 clear:both;
 display:block;
}

May be that's help you.

sandeep
  • 91,313
  • 23
  • 137
  • 155
2

I had the same problem. After adding this lines, my dropdown worked just as I expected:

@media (max-width: 767px) {
    .table-responsive .dropdown-menu {
        position: static !important;
    }
}

@media (min-width: 768px) {
    .table-responsive {
        overflow: visible;
    }
}

I found the solution here

Jorge Casariego
  • 21,948
  • 6
  • 90
  • 97
  • Thanks! It worked on desktop and tablet, but positioning was a bit whacky on iPhone 6+, I changed the max-width 767px to comment out the position and used left: -100px; ... Yep, hacky, but it works. – RobbiewOnline Feb 27 '18 at 16:46
1

NEW METHOD:

Just bring drop down menu out of media class and use a negative margin:

 <div class="dropdown pull-right" style="margin-left:-30px">
     ...
 </div>

 <div class="media">
     ...
 </div>
hjahan
  • 370
  • 3
  • 13
0

Get this quite often on projects I inherit; tends to be a case of one of the parent elements having

overflow:hidden

Once I remove this it seems to work as expected (as long as your design doesn't rely on this property).

Kyle Fowlie
  • 63
  • 1
  • 6
Wellso
  • 1
0

Based on @nick answer, this is what I do in Bootstrap 3 without Jquery UI.

        let dropdown_toggles = $('.my-table .dropdown-toggle');
        dropdown_toggles.each(function (index, elem) {
            let dropdownMenu;
            let dropdown_toggle = $(elem);
            dropdown_toggle.dropdown();
            dropdown_toggle.parent().on('show.bs.dropdown', function(e) {
                let $target = $(e.target);
                let $relatedTarget = $(e.relatedTarget).parent();
                dropdownMenu = $target.find('.dropdown-menu');
                dropdownMenu.css({
                    'position': 'absolute',
                    'z-index': 1,
                    'top': ($relatedTarget.offset().top + $relatedTarget.height()) + 'px',
                    /*'left': $relatedTarget.offset().left + 'px',*/ //from left
                    'left': ($relatedTarget.offset().left - dropdownMenu.width() + $relatedTarget.width()) + 'px', //from right
                });
                $('body').append(dropdownMenu.detach());
                dropdownMenu.css('display', 'block');
            });
            dropdown_toggle.parent().on('hide.bs.dropdown', function(e) {
                $(e.target).append(dropdownMenu.detach());
                dropdownMenu.hide();
            });
        });

This will allow you to set from left or right with position absolute.